Règles de recherche pour les dépendances des DLL du serveur COM

Considérez l’organisation de fichiers suivante sous Windows:

[app folder] app.exe [folder 'sub'] com_server.dll regular.dll helper.dll 

Supposons également ce qui suit:

  • Com_server.dll et regular.dll sont tous deux liés de manière statique à une fonction dans helper.dll, de sorte que helper.dll est chargé lorsqu’ils le sont.
  • app.exe n’a pas de dépendances statiques.
  • Les objects COM com_server.dll sont enregistrés avec Windows
  • le dossier ‘sub’ n’est pas dans le chemin du système.

Considérons les cas suivants:

  1. app.exe appelle LoadLibrary (“sub / regular.dll”). Cela échouera, car Windows ne pourra pas trouver helper.dll, conformément à la procédure de recherche de DLL documentée.
  2. app.exe appelle CoCreateInstance pour créer un object implémenté dans com_server.dll. Cela réussit et helper.dll est chargé.

Les principales questions: Pourquoi l’affaire 2 fonctionne-t-elle? Quels sont les détails de la procédure de recherche de DLL dépendante pour le cas du serveur COM?

Il semblerait que lors de la création d’un object com avec CoCreateInstance, le dossier de la DLL d’implémentation soit en quelque sorte ajouté au chemin de recherche des dépendances. Est-ce ce qui se passe et est-ce garanti? Je ne trouve aucune documentation où que ce soit qui traite de ce cas.

Regardons la documentation de LoadLibrary sur MSDN :

Si la chaîne spécifie un chemin complet, la fonction recherche uniquement ce chemin pour le module. Si la chaîne spécifie un chemin relatif ou un nom de module sans chemin, la fonction utilise une stratégie de recherche standard pour trouver le module; pour plus d’informations, voir les remarques.

Ok, donc cela explique le comportement de # 1 ci-dessus. Si vous aviez dit:

 LoadLibrary("C:\\program files\\AppFolder\\Sub\\com_server.dll") 

Ensuite, cela aurait trouvé vos DLL dépendantes, et LoadLibrary aurait réussi.

En ce qui concerne le succès de COM avec # 2, cela dépend vraiment de la manière dont com_server.dll est enregistré dans le registre pour la clé InProcServer32. S’il s’agit d’un chemin d’access complet au fichier, LoadLibrary fonctionnera comme décrit ci-dessus. Si c’est un chemin relatif, je soupçonne que COM pourrait faire un certain nombre de choses pour que la recherche de DLL comme le vôtre fonctionne.

Une possibilité est que CoCreateInstance appelle LoadLibraryEx avec l’indicateur LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR . Il peut même appeler LoadLibrary (Ex) plusieurs fois avec différentes combinaisons de drapeaux.

De plus, étant donné que CoCreateInstance est une API système, il est tout à fait possible qu’elle ait une version interne privée de LoadLibrary qui permette des chemins de recherche alternatifs.