L'éditeur de liens MSVC peut lier des fichiers objets (.obj) et des bibliothèques d'objets (.lib) pour produire un .EXE ou un .DLL.
Pour établir un lien avec une DLL, le processus dans MSVC consiste à utiliser une bibliothèque dite d'importation (.LIB) qui agit comme une colle entre les noms de fonction C et la table d'exportation de la DLL (dans une DLL, une fonction peut être exportée par nom ou par ordinal - ce dernier était souvent utilisé pour les API non documentées).
Cependant, dans la plupart des cas, la table d'exportation DLL contient tous les noms de fonction et donc la bibliothèque d'importation (.LIB) contient des informations largement redondantes ("fonction d'importation ABC -> fonction exportée ABC ", etc).
Il est même possible de générer une .LIB à partir d'une .DLL existante.
Les éditeurs de liens sur d'autres plates-formes n'ont pas cette "fonctionnalité" et peuvent se lier directement aux bibliothèques dynamiques.
Sous Linux, l'éditeur de liens (pas l'éditeur de liens dynamique) recherche dans les bibliothèques partagées spécifiées au moment de la liaison et crée des références à celles-ci dans l'exécutable. Lorsque l'éditeur de liens dynamique charge ces exécutables, il charge les bibliothèques partagées dont ils ont besoin en mémoire et résout les symboles, ce qui permet d'exécuter les binaires.
MySo.a
, s'il était créé, inclurait en fait les symboles à lier directement dans le binaire au lieu des "tables de recherche de symboles" utilisées sous Windows.
La réponse de rustyx explique le processus sous Windows plus en détail que moi ; cela fait longtemps que je n'utilise pas Windows.
La différence que vous voyez est plus un détail d'implémentation - sous le capot, Linux et Windows fonctionnent de la même manière - votre code appelle une fonction stub qui est liée statiquement dans votre exécutable et ce stub charge ensuite DLL/shlib si nécessaire (en cas de retard chargement, sinon la bibliothèque est chargée au démarrage du programme) et (au premier appel) résout le symbole via GetProcAddress
/dlsym
.
La seule différence est que sous Linux, ces fonctions stub (appelées stubs PLT) sont générées dynamiquement lorsque vous liez votre application à une bibliothèque dynamique (la bibliothèque contient suffisamment d'informations pour les générer), alors que sous Windows, elles sont plutôt générées lors de la création de la DLL elle-même, dans un .lib
séparé fichier.
Les deux approches sont si similaires qu'il est en fait possible d'imiter les bibliothèques d'importation Windows sur Linux (voir le projet Implib.so).