在C#中,我正在尝试使用C ++中的“简单”函数。问题是我在编译时不知道库的名称或位置。在C ++中,这很容易:
typedef HRESULT (*SomeFuncSig)(int, IUnknown *, IUnknown **);
const char *lib = "someLib.dll"; // Calculated at runtime
HMODULE mod = LoadLibrary(lib);
SomeFuncSig func = (SomeFuncSig)GetProcAddress("MyMethod");
IUnknown *in = GetSomeParam();
IUnknown *out = NULL;
HRESULT hr = func(12345, in, &out);
// Leave module loaded to continue using foo.
对于我的生活,我无法弄清楚如何在C#中做到这一点。如果我知道dll名称,我就不会有任何麻烦,它会像这样看起来像 :
[DllImport("someLib.dll")]
uint MyMethod(int i,
[In, MarshalAs(UnmanagedType.Interface)] IUnknown input,
[Out, MarshalAs(UnmanagedType.Interface)] out IUnknown output);
如果不知道我在编译时加载的dll怎么办呢?
答案 0 :(得分:7)
你以同样的方式做到这一点。声明一个委托类型,其签名与导出的函数匹配,就像SomeFuncSig一样。 Pinvoke LoadLibrary和GetProcAddress获取导出函数的IntPtr,就像在C ++中一样。然后使用Marshal.GetDelegateForFunctionPointer()创建委托对象。
答案 1 :(得分:5)
这是一个解决方案:Dynamically calling an unmanaged dll from .NET (C#)(基于LoadLibrary / GetProcAddress)
答案 2 :(得分:1)
如果您事先知道DLL名称,并且事先知道了函数名称,则有一种更简单的方法。
您可以简单地声明P / Invoke签名,然后使用LoadLibrary
根据配置文件条目加载DLL。只要您在使用任何P / Invoke函数之前成功调用LoadLibrary
,它们就会成功,因为已经加载了DLL。