Comment fonctionnent les bibliothèques d’importation et pourquoi MinGW n’en a-t-il pas besoin?

J’ai regardé cette page: Un examen approfondi du format de fichier exécutable portable Win32

Il explique que l’éditeur de liens a besoin d’une bibliothèque d’importation car le compilateur ne peut pas faire la distinction entre les appels de fonction normaux et les appels de fonction API. Mais ils disent aussi que __declspec (dllimport) spécifie un appel de fonction pour être un appel API, donc le lieur se lie à __imp_[ function-name ] . Mais avec ce mot-clé, le compilateur doit savoir qu’il s’agit d’un appel à une fonction API.

Pourquoi l’éditeur de liens a-t-il encore besoin d’une bibliothèque d’importation? Le compilateur pourrait marquer ce symbole comme importé en ajoutant __imp_ au nom de la fonction et pourrait appeler un pointeur de fonction (qui est encore un symbole non résolu) et l’éditeur de liens pourrait remplacer ce symbole (car il voit cet appel d’API) avec l’adresse de l’entrée IAT.

Et pourquoi l’éditeur de liens MinGW peut-il utiliser “DLL MinGW” directement, mais l’éditeur de liens Visual-Studio a besoin d’une bibliothèque d’importation?

En lisant le post, d’autres questions ont également été soulevées. Comment le “dlltool (ou l’éditeur de liens)” (selon ce qui crée la bibliothèque d’importation) connaît-il l’emplacement d’une entrée IAT avant que le lien avec l’exécutable final ait été effectué? Je pensais que les entrées IAT seraient construites au moment du lien avec l’exécutable final. Le post dit que chaque appel API a une position fixe dans la table IAT, sans compter le nombre de DLL qui seront liés. Je ne peux pas imaginer comment cela pourrait être réalisé.

Il est possible de créer un lien vers une DLL sans bibliothèque d’importation, comme le montre clairement MinGW. D’où la question est pourquoi MSVC a décidé d’omettre cette fonctionnalité.

Les raisons sont principalement historiques.

En 1983, à l’époque de la création de Windows et de la création de DLL, il existait de nombreuses chaînes d’outils (compilateurs, éditeurs de liens) de différents fournisseurs. Sortir demander aux fournisseurs d’implémenter le support pour lier des “DLL” à un système d’exploitation minoritaire n’était clairement pas une option.

Ils ont donc décidé d’écrire un outil pour générer une bibliothèque à laquelle tout le monde et leur chien pourraient se lier, même si un éditeur de liens n’avait absolument aucune idée des DLL.

En outre, les bibliothèques d’importation offrent des fonctionnalités essentielles il ya trois décennies, mais elles sont désormais obsolètes. La première est la possibilité d’importer un symbole par ordinal – c.-à-d. Que la DLL a la possibilité de ne proposer aucun nom uniquement une liste d’adresses; l’ordinal est un index dans cette liste. Fait quand la quantité de RAM était très limitée.

Deuxièmement, le soutien aux différents schémas de gestion de noms. Même en C, il existe un schéma de gestion des noms, par exemple FooBar peut devenir _FooBar @ 4 (cela dépend de la plate-forme et de la convention d’appel). Il était parfaitement logique qu’une DLL exporte “FooBar” sur chaque plate-forme prise en charge pour la cohérence (et rend la vie de l’utilisateur GetProcAddress () plus facile). La bibliothèque d’importation implémente le mappage de _FooBar @ 4 vers FooBar.

Ceci est basé sur le blog ( 1 , 2 ) de Raimond Chen, l’homme qui a été impliqué dans le développement de Windows dès le début.