Importation d’appels de fonction à l’aide de __declspec(dllimport)
L’annotation des appels à l’aide de la __declspec(dllimport)
méthode peut les rendre plus rapides. __declspec(dllimport)
est toujours nécessaire pour accéder aux données DLL exportées.
Importer une fonction à partir d’une DLL
L’exemple de code suivant montre comment importer __declspec(dllimport)
des appels de fonction à partir d’une DLL dans une application. Supposons qu’il func1
s’agit d’une fonction qui se trouve dans une DLL distincte du fichier exécutable qui contient la fonction principale .
Sans __declspec(dllimport)
, étant donné ce code :
int main(void)
{
func1();
}
le compilateur génère du code qui ressemble à ceci :
call func1
et l’éditeur de liens traduit l’appel en quelque chose comme ceci :
call 0x4000000 ; The address of 'func1'.
S’il func1
existe dans une autre DLL, l’éditeur de liens ne peut pas résoudre cette adresse directement, car il n’a aucun moyen de connaître l’adresse de func1
l’objet. Dans les environnements 32 bits et 64 bits, l’éditeur de liens génère un thunk à une adresse connue. Dans un environnement 32 bits, le thunk ressemble à ceci :
0x40000000: jmp DWORD PTR __imp_func1
Voici __imp_func1
l’adresse de l’emplacement func1
dans la table d’adresses d’importation du fichier exécutable. Toutes ces adresses sont connues de l’éditeur de liens. Le chargeur doit uniquement mettre à jour la table d’adresses d’importation du fichier exécutable au moment du chargement pour que tout fonctionne correctement.
C’est pourquoi l’utilisation __declspec(dllimport)
est meilleure : parce que l’éditeur de liens ne génère pas de thunk s’il n’est pas nécessaire. Les thunks rendent le code plus grand (sur les systèmes RISC, il peut s’agir de plusieurs instructions) et peuvent dégrader les performances de votre cache. Si vous indiquez au compilateur que la fonction se trouve dans une DLL, elle peut générer un appel indirect pour vous.
Ainsi, maintenant, ce code :
__declspec(dllimport) void func1(void);
int main(void)
{
func1();
}
génère cette instruction :
call DWORD PTR __imp_func1
Il n’y a pas de thunk et aucune jmp
instruction, donc le code est plus petit et plus rapide. Vous pouvez également obtenir le même effet sans __declspec(dllimport)
utiliser l’optimisation complète du programme. Pour plus d’informations, consultez l’article /GL (Optimisation de l’ensemble du programme).
Pour les appels de fonction au sein d’une DLL, vous ne souhaitez pas avoir à utiliser un appel indirect. L’éditeur de liens connaît déjà l’adresse de la fonction. Il faut du temps et de l’espace supplémentaires pour charger et stocker l’adresse de la fonction avant un appel indirect. Un appel direct est toujours plus rapide et plus petit. Vous souhaitez uniquement utiliser __declspec(dllimport)
lors de l’appel de fonctions DLL en dehors de la DLL elle-même. N’utilisez __declspec(dllimport)
pas de fonctions à l’intérieur d’une DLL lors de la génération de cette DLL.