2012-10-03 5 views
2

Je fais beaucoup de programmation sous Linux et j'utilise l'attribut visibility pour définir si un symbole est visible ou caché dans l'objet partagé. Simplement pour rendre les choses plus claires: si un symbole est visible, il sera accessible à l'extérieur (quelqu'un qui se connecte à l'objet partagé), s'il est caché, il est censé être utilisé uniquement en interne. Sur les fenêtres, cela semble fonctionner un peu différemment, cela fonctionne avec l'export (le symbole est défini ici dans l'objet partagé et sera accessible par quelqu'un qui s'y connecte) et l'importation (ici je suis en train de créer un lien avec un objet partagé). le symbole y est exporté) symboles. Mais je ne pouvais pas trouver un moyen de dire au compilateur de ne pas exporter un symbole, car il doit être utilisé uniquement ici, c'est-à-dire, si quelqu'un établit un lien avec lui, une erreur de lien est attendue.Visibilité des symboles sous Windows

Ma question est de savoir si je peux définir un symbole comme "caché" (comme dans gcc de Linux) et comment. En outre, toute cette visibilité dans le sujet Windows est un peu floue pour moi et je cherchais d'autres liens de lecture pour mieux comprendre comment tout fonctionne.

+1

Pas un développeur Windows, mais s'il n'est pas exporté ('dllexport'), n'est-il pas * invisible * par défaut? –

+0

@ DavidRodríguez-dribeas Je n'ai aucune expérience avec le studio visuel (commençant à faire du code compatible avec msvc pour l'instant), mais sur mingw il semble être visible par défaut. –

+0

http://gcc.gnu.org/wiki/Visibility montre les deux façons. –

Répondre

5

David Rodriguez a raison, dans l'environnement MSVC, le programmeur exporte généralement explicitement les symboles de fonction/classe via le modificateur __declspec(dllexport) spécifique à MSVC. Les symboles qui ne sont pas explicitement exportés ne doivent pas apparaître dans la table de symboles pour la DLL compilée (vous pouvez utiliser dumpbin, l'un des utilitaires de ligne de commande Visual Studio, pour vérifier, en utilisant l'option/EXPORTS). Il est convention d'utiliser dllimport lorsque vous importez ce symbole, même si je crois que c'est facultatif. Généralement, les fichiers d'en-tête définissant l'interface publique d'une DLL possèdent une macro qui se développe par défaut sur __declspec (dllimport), mais qui est définie sur __declspec (dllexport) pendant la construction de cette bibliothèque.

Notez que comment GCC et MSVC traitent dllexport peuvent être différents; peut-être que GCC ne «respecte» pas dllexport dans le sens de cacher des symboles non exportés? Je voudrais d'abord essayer de compiler avec MSVC et tester ces résultats avec dumpbin avant d'essayer la même chose avec GCC. Si vous n'avez pas Visual Studio, vous pouvez toujours obtenir un compilateur MSVC soit en téléchargeant VS Express, ou (moins connu) en téléchargeant certains redistribuables .NET qui sont livrés avec la ligne de commande MSVC (ces deux options sont gratuites et légitimes). VS Express peut être le meilleur choix ici, donc vous pouvez obtenir dumpbin.

+0

Sous MSVC, vous pouvez également exporter via le fichier de définition du module (.def), auquel cas le declspecs() peut être lancé entièrement sous le bus (et en fonction des paramètres de construction, * doit * être). – WhozCraig

+0

@WhozCraig N'a pas utilisé .def beaucoup avant, mais je crois que vous avez raison. Les auteurs de la bibliothèque font le choix entre ces deux méthodes, donc l'existence de .def en tant qu'option n'empêche pas l'op de choisir dllexport et de l'utiliser pour limiter de manière semi-efficace la visibilité sous MSVC. – WeirdlyCheezy

+0

Totalement. J'ai trouvé dans le passé que définir des entrées exposées spécifiques dans les DLL sous Windows est * tellement * plus propre que Linux simplement parce que l'exposition par défaut n'est pas du tout, mais je passe plus de temps avec l'un que l'autre. à ce propos. – WhozCraig

Questions connexes