2010-10-10 4 views
3

Dans Visual Studio, vous créez un projet .dll et il crée des fichiers .dll et .lib. Vous liez statiquement au .lib, et si le .dll est dans le même dossier que le .exe, tout fonctionne.Comment charger automatiquement des DLL à partir d'un sous-répertoire?

Je suspecte que tout fonctionnerait aussi si le .dll était dans System32 ou n'importe quel autre dossier de PATH (confirmer ou corriger, svp).

Mais voici la question: Je veux que mon exe trouve le fichier .dll dans ./DLLS/ dossier, c'est, si mon exe est ....../MyApp/MyApp.exe alors il devrait chercher le fichier .dll dans ...../MyApp/DLL/MyDll.dll. Je ne veux pas inclure le dossier DLL dans le chemin. Y a-t-il un moyen de le faire?

Veuillez noter que je ne souhaite pas utiliser explicitement LoadLibrary, je ne peux donc pas spécifier le chemin d'accès.

Merci d'avance pour toute aide.

+0

http://stackoverflow.com/a/36644602/321013. ... Vous pouvez utiliser un manifeste d'assemblage privé –

Répondre

2

Vous pouvez utiliser SetDllDirectory pour cela. Le chargeur utilisera le répertoire supplémentaire que vous spécifiez lors du chargement des bibliothèques. Cependant, il ne peut y avoir qu'un seul répertoire supplémentaire, vous devez donc vous assurer qu'il n'y aura pas d'autres appels à cela plus tard dans votre application, sinon le répertoire que vous spécifiez sera ignoré.

Si cette API n'autorise pas les répertoires relatifs (je ne suis pas sûr), vous pouvez toujours appeler GetModuleFileName avec un premier paramètre NULL pour obtenir le nom de fichier du programme en cours d'exécution. Avec une petite manipulation de chaîne, vous pouvez obtenir le chemin absolu vers votre dossier DLL.

+1

Et où dois-je l'utiliser exactement? Avant la tentative de chargement de la DLL, non? mais dans le scénario décrit (lien statique vers lib qui charge automatiquement la DLL) la DLL est chargée au démarrage ... –

+2

@Armen: bon point, oui, cela doit être fait avant le chargement de la DLL. Si vous n'utilisez pas la DLL immédiatement dans votre application, vous pouvez spécifier qu'il s'agit d'une dépendance de délai (voir http://msdn.microsoft.com/en-us/library/yx9zd12s.aspx). Cela empêchera le chargement de la DLL tant que vous n'avez pas effectué votre premier appel. Ceci est similaire à l'appel 'LoadLibrary', mais il est fait pour vous automatiquement. –

3

Voici la séquence par défaut les applications Win32 passent par lors de la recherche d'une DLL:

http://msdn.microsoft.com/en-us/library/7d83bc18(VS.80).aspx

Ainsi, selon cette autre approche pourrait consister à appeler SetCurrentDirectory ou SetDllDirectory. Mais pour que cela fonctionne, vous devez utiliser la fonctionnalité Delay Loaded Library (vous spécifiez cela dans les paramètres du projet dans Visual Studio). La bibliothèque à chargement différé signifie que la DLL est chargée uniquement au moment où le programme en a besoin, pas automatiquement au démarrage des programmes.

+0

Est-ce que vous laissez entendre que si je n'utilise pas la charge de retard, je ne peux pas réaliser ce que je veux? –

+1

@Armen: si vous ne chargez pas (ou ne pouvez pas) retarder le chargement de votre bibliothèque, il s'agira d'une dépendance au chargement qui sera chargée lors du chargement de votre processus. Cela se produira avant que votre code ne s'exécute, vous ne pourrez donc pas appeler 'SetDllDirectory' et le chargement échouera. Si vous n'avez pas besoin de la fonctionnalité de la DLL immédiatement (c'est-à-dire avant 'main'), la dépendance au chargement de retard est correcte. –

+0

@Chris: Ok, en fait je n'ai pas besoin de la fonctionnalité de dll avant main, donc je peux ajouter SetDllDirectory comme première instruction dans main, et tout ira bien. Je comprends, mais qu'en est-il d'un cas théorique où la fonctionnalité est nécessaire avant main? Il n'y a pas d'autre moyen que de placer la DLL dans le même dossier ou d'ajouter le répertoire à PATH? Ce serait étrange ... Je veux dire, il y a BOUND pour être une propriété de configuration que je ne trouve pas ... –

Questions connexes