问题描述
我在Managed C ++中开发了一个DLL,它在运行时使用。所有插件实现的接口在C#中实现。它由Managed C ++代码使用,如下所示:
I developed a DLL in Managed C++ which loads some plugins (implemented in any .NET language) at runtime using System.Reflection.Assembly.LoadFile. The interface which is implemented by all plugins is implemented in C#. It's used by the Managed C++ code like this:
#using <IMyPluginInterface.dll> // Make the 'IMyPluginInterface' type available
ref class PluginManager {
List<IMyPluginInterface ^> ^m_plugins;
// Load all plugins in a well-known directory.
void load() {
for ( string 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 ) );
}
}
}
加载插件效果很好;我面临的问题是在运行时, IMyPlugnInterface.dll
文件可能不在与Managed C ++ DLL相同的目录中。这意味着'IMyPluginInterface'类型在运行时不可用,并且抛出异常。
Loading the plugins works well; the problem I'm facing is that at runtime, the IMyPlugnInterface.dll
file might not be in the same directory as the Managed C++ DLL. This means that the 'IMyPluginInterface' type is not available at runtime, and an exception is thrown.
我之前问过是否可能影响使用的查找路径通过 #using
语句解析引用的DLL。不幸的是,这没有产生任何结果。
I previously asked whether it was maybe possible to influence the lookup path used when resolving DLLs referenced via the #using
statement. Unfortunately, this didn't yield any result.
这可能有不同的方法吗?通过 #using
引用的类型是否可以编译到Managed C ++ DLL中?也许任何人都有一个完全不同的解决方案?
Is there maybe a different approach to this? Can types which are referenced via #using
be compiled into the Managed C++ DLL? Maybe anybody else has an entirely different solution?
推荐答案
你可以使用几个选项 - 如果你提前知道程序集您可以将该路径添加到应用程序的配置文件中:
You can use several options - if you know in advance where the assembly will be located, you can add that path to your application's configuration file:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="MyPath"/>
</assemblyBinding>
</runtime>
</configuration>
如果要在运行时搜索程序集,可以实现 AppDomain :: CurrentDomain-> AssemblyResolve
event:
If you want to search for the assembly at runtime, you can implement a handler for AppDomain::CurrentDomain->AssemblyResolve
event:
ref class AssemblyResolver
{
public:
/// The path where the assemblies are searched
property String^ Path
{
String^ get()
{ return path_; }
}
explicit AssemblyResolver(String^ path)
: path_(path)
{ /* Void */ }
Assembly^ ResolveHandler(Object^ sender, ResolveEventArgs^ args)
{
// The name passed here contains other information as well
String^ dll_name = args->Name->Substring(0, args->Name->IndexOf(','));
String^ path = System::IO::Path::Combine(path_, dll_name+".dll");
if ( File::Exists(path) )
return Assembly::LoadFile(path);
return nullptr;
}
private:
String^ path_;
};
,您可以使用以下方式连线:
and you can wire it using something like this:
AssemblyResolver^ resolver = gcnew AssemblyResolver(path);
AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler(
resolver,
&AssemblyResolver::ResolveHandler
);
只需确保在调用任何可能使用来自程序集类型的方法已解决。
Just make sure this is done before calling any methods that may use types from the assembly that has to be resolved.
这篇关于如何更改通过#using在Managed C ++中引用的.NET库的查找路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!