Comment modifier le chemin de recherche des bibliothèques .NET référencées via #using en Managed C ++?

J’ai développé une DLL en C ++ managé qui charge des plugins (implémentés dans n’importe quel langage .NET) lors de l’exécution à l’aide de System.Reflection.Assembly.LoadFile . L’interface qui est implémentée par tous les plugins est implémentée en C #. Il est utilisé par le code Managed C ++ comme ceci:

#using  // Make the 'IMyPluginInterface' type available ref class PluginManager { List ^m_plugins; // Load all plugins in a well-known directory. void load() { for ( ssortingng dllFile in Directory.GetFiles( .., "*.dll" ) ) { // Lookup the type of the plugin object using Reflection Type pluginType = ...; // Finally, instantiate the plugin and add it to our list. m_plugins.Add( (IMyPluginInterface ^)Activator.CreateInstance( pluginType ) ); } } } 

Le chargement des plugins fonctionne bien; le problème auquel je suis confronté est qu’au moment de l’exécution, le fichier IMyPlugnInterface.dll pourrait ne pas se trouver dans le même répertoire que la DLL IMyPlugnInterface.dll ++ C ++. Cela signifie que le type ‘IMyPluginInterface’ n’est pas disponible au moment de l’exécution et qu’une exception est levée.

J’ai déjà demandé s’il était possible d’influencer le chemin de recherche utilisé lors de la résolution des DLL référencées via l’instruction #using . Malheureusement, cela n’a donné aucun résultat.

Y at-il peut-être une approche différente à cela? Les types référencés via #using peuvent- #using être compilés dans la DLL #using ++ C ++? Peut-être que quelqu’un d’autre a une solution totalement différente?

Vous pouvez utiliser plusieurs options. Si vous savez à l’avance l’emplacement de l’assemblage, vous pouvez append ce chemin d’access au fichier de configuration de votre application:

        

Si vous souhaitez rechercher l’assembly au moment de l’exécution, vous pouvez implémenter un gestionnaire pour l’événement AppDomain::CurrentDomain->AssemblyResolve :

 ref class AssemblyResolver { public: /// The path where the assemblies are searched property Ssortingng^ Path { Ssortingng^ get() { return path_; } } explicit AssemblyResolver(Ssortingng^ path) : path_(path) { /* Void */ } Assembly^ ResolveHandler(Object^ sender, ResolveEventArgs^ args) { // The name passed here contains other information as well Ssortingng^ dll_name = args->Name->Subssortingng(0, args->Name->IndexOf(',')); Ssortingng^ path = System::IO::Path::Combine(path_, dll_name+".dll"); if ( File::Exists(path) ) return Assembly::LoadFile(path); return nullptr; } private: Ssortingng^ path_; }; 

et vous pouvez le câbler en utilisant quelque chose comme ceci:

 AssemblyResolver^ resolver = gcnew AssemblyResolver(path); AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler( resolver, &AssemblyResolver::ResolveHandler ); 

Assurez-vous simplement que cela est fait avant d’appeler des méthodes susceptibles d’utiliser des types de l’assembly à résoudre.

N’est-ce pas la stratégie de résolution d’assemblages .net standard? Voir ici pour une introduction détaillée.