que signifie vraiment __declspec (dllimport)?


Réponses:


118

__declspecest un attribut spécifique à Microsoft qui vous permet de spécifier des informations de classe de stockage.
(Nitpicker's Corner: Cependant, un certain nombre d'autres fournisseurs de compilateurs - par exemple GCC - prennent désormais en charge cette extension de langage pour la compatibilité avec la base de code installée qui a été écrite pour les compilateurs de Microsoft. Certains fournissent même des attributs de classe de stockage supplémentaires.)

Deux de ces attributs de classe de stockage qui peuvent être spécifiés sont dllimportet dllexport. Ceux-ci indiquent au compilateur qu'une fonction ou un objet est importé ou exporté (respectivement) à partir d'une DLL.

Plus spécifiquement, ils définissent l'interface de la DLL avec le client sans avoir besoin d'un .DEFfichier module-definition ( ). La plupart des gens trouvent qu'il est beaucoup plus facile d'utiliser ces extensions de langage que de créer des fichiers DEF.

Pour des raisons évidentes, __declspec(dllimport)et __declspec(dllexport)sont généralement jumelés les uns aux autres. Vous utilisez dllexportpour marquer un symbole comme exporté à partir d'une DLL et vous utilisez dllimportpour importer ce symbole exporté dans un autre fichier.

Pour cette raison, et comme le même fichier d'en-tête est généralement utilisé à la fois lors de la compilation de la DLL et dans le code client qui consomme l'interface de la DLL, il s'agit d'un modèle courant pour définir une macro qui se résout automatiquement en spécificateur d'attribut approprié au moment de la compilation. Par exemple:

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

Et puis en marquant tous les symboles avec lesquels exporter DLLEXPORT.

Vraisemblablement, c'est ce que fait la Q_CORE_EXPORTmacro, résolvant soit Q_DECL_IMPORTou Q_DECL_EXPORT.


__declspec n'est pas correctement "spécifique à MS" (il est beaucoup plus "spécifique au compilateur) et certains compilateurs utilisent également cette déclaration pour plusieurs plates-formes. Certaines des valeurs d'attributs sont (dllexport / dllimports sont spécifiques à MS, en fait, puisque DLL est MS lexique).
Emilio Garavaglia

9
@Emilio: Autant que je sache, Microsoft a inventé la __declspecnotation comme une extension du langage C ++. Je pense que GCC le prend désormais en charge, mais c'est principalement pour des raisons de compatibilité avec les compilateurs de Microsoft. Et je ne comprends pas en quoi «spécifique à MS» est différent de «spécifique au compilateur». Microsoft a écrit un compilateur C ++ et beaucoup de gens l'utilisent. Il est livré avec Visual Studio.
Cody Gray

8
Microsoft crée un compilateur. Il s'appelle le «compilateur d'optimisation Microsoft C / C ++», cl.exe. Beaucoup de gens font référence à tort à Visual Studio comme s'il s'agissait d'un compilateur, mais c'est un IDE. Je ne sais pas pourquoi les gens se demandent ce que signifie «spécifique à Microsoft». Cela ne signifie pas un "environnement MS" (quoi que ce soit), et cela ne signifie certainement pas "Windows". Oui, d'autres fournisseurs de compilateurs prennent désormais en charge l'extension pour la compatibilité avec la base installée de code écrit ciblant les compilateurs Microsoft. Comme je l'ai déjà dit, pour autant que je sache, Microsoft a inventé la syntaxe. C'est le point soulevé ici.
Cody Gray

2
@CodyGray: Microsoft l'ayant inventé seul ne suffirait pas. Cependant, Microsoft l'ayant inventé, aucun standard ne le contenant, d'autres ne l'implémentant que pour la compatibilité et il est utilisé principalement (sinon exclusivement) pour les programmes ciblant Microsoft Windows ensemble font un point très fort pour le qualifier de "spécifique à Microsoft"
celtschk

6
C'est une réponse géniale, en particulier la partie sur "car le même fichier d'en-tête est généralement utilisé à la fois lors de la compilation de la DLL et dans le code client"! Rend chaque aspect de l'importation / exportation clair comme du cristal.
Ela782

30

__declspec(dllimport) est un spécificateur de classe de stockage qui indique au compilateur qu'une fonction, un objet ou un type de données est défini dans une DLL externe.

La fonction ou l'objet ou le type de données est exporté à partir d'une DLL avec un fichier __declspec(dllexport).


6
D'accord. Enfin, après 2 heures de lecture, j'ai trouvé l'énoncé le plus satisfaisant, le plus concis, le plus précis de ce que je veux.
el psy Congroo

1

__declspec(dllexport)indique au compilateur d'informer l'éditeur de liens que ces symboles doivent être placés dans la table d'exportation (lors de la compilation du fichier .dll). Lors de la compilation du programme qui relie avec le fichier .dll, __declspec(dllimport)indique au compilateur de produire un appel indirect indirect indirect de registre absolu relatif à la déchirure (que l'éditeur de liens remplira pour pointer vers la table d'importation) plutôt que l'habituel registre direct relatif à ripinstruction d'appel indirect à une fonction indéfinie (qui, comme il ne peut pas modifier l'instruction, l'éditeur de liens insère l'adresse relative d'un thunk puis crée le thunk, à l'intérieur duquel il place l'appel indirect indirect de registre absolu relatif à la déchirure vers le pointeur de fonction dans la table d'importation). Il s'agit d'une optimisation de la taille et de la vitesse du code. C'est la bibliothèque d'importation .lib qui indique à l'éditeur de liens les symboles qui seront importés et est utilisée comme guide pour créer la table d'importation et créer tous les thunks nécessaires dans le segment .text.

https://docs.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / importing-data-using-declspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.