简介
我的程序允许其他开发人员编写插件。这些插件(是dll文件)放在某个目录中,我的程序能够在运行时加载它们,如下所示:
Assembly assembly = Assembly.LoadFrom("MyPluginPath");
object Plugin = assembly.CreateInstance("Plugins.Main", true);
然后程序将能够以这种方式从插件中调用main
方法:
var pluginType = Plugin.GetType();
var methodOutput = pluginType.GetMethod("MyInternalMethod").Invoke(Plugin, new object[] {param});
这对我到目前为止所写的所有插件都有效,这些插件遵循以下特定结构:
namespace Plugins
{
public class Main : IDisposable
{
public Bitmap MyInternalMethod(Bitmap param)
{
// method body
}
}
}
问题
现在有一个我要编写的新插件,它在运行时加载外部dll:
namespace Plugins
{
public class Main : IDisposable
{
[System.Runtime.InteropServices.DllImport("MyExternalDLL.dll")]
unsafe private static extern int Initialize(int* arg1, char* arg2);
public Bitmap MyInternalMethod(Bitmap param)
{
// method body
Initialize(x,y);
}
}
}
上面代码中的 Initialize(x,y)
方法给出了一个错误,上面写着
无法初始化com库。
备注
Func<>
对象传递给我的插件,但Func<>
不允许指针变量(Initialize
方法包含int*
和char*
等参数,即使它确实存在,我也不确定这个解决方案是否会起作用。winApi
作为“Sinatr”在评论中建议按照this回答,但错误仍然存在。我甚至尝试使用MyExternalDLL.dll
在主程序中加载winApi
并将检索到的Initialize
方法地址传递给我的插件,如下面的代码,但错误保持不变(这种方式错误发生在func(x,y)
):主程序:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string name);
IntPtr dllHandle = IntPtr.Zero;
IntPtr addr = IntPtr.Zero;
private void RunPlugin()
{
dllHandle = LoadLibrary("MyExternalDLL.dll");
addr = GetProcAddress(dllHandle, "Initialize");
var methodOutput = pluginType.GetMethod("MyInternalMethod").Invoke(Plugin, new object[] {param, addr});
}
插件:
public class Main : IDisposable
{
private unsafe delegate byte initialize_api(int* arg1, char* arg2);
public Bitmap MyInternalMethod(Bitmap param, IntPtr addr)
{
// method body
//initialize_api is a delegate with the same signature as Initialize(x,y);
var func = (initialize_api)Marshal.GetDelegateForFunctionPointer(addr, typeof(initialize_api));
func(x,y);
}
}
Interface
。问题
是否甚至可以像我描述的那样使用包含动态加载的dll的动态加载的dll?如果是的话,我该怎么做才能使这项工作?