2011-09-30 72 views
6

在C#中,我想的PInvoke一个“简单”的功能,我在C++。问题是在编译时我不知道库的名称或位置。在C++中,这很容易:PInvoke在编译时不知道DLL吗?

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?

回答

5

祢是这里的解决方案:Dynamically calling an unmanaged dll from .NET (C#)(基于调用LoadLibrary/GetProcAddress的)

+0

我缺少的东西?要使用LoadLibrary,您*需要知道dll的名称。如果OP _knew_ dll的名字,他不会尝试在第一个地方找到不同的解决方案。编辑:认为我错过了“在编译时”vs“在运行时”。 –

7

你做同样的方式。声明一个签名与导出函数匹配的委托类型,就像SomeFuncSig一样。 Pinvoke LoadLibrary和GetProcAddress来获取导出函数的IntPtr,就像在C++中一样。然后用Marshal.GetDelegateForFunctionPointer()创建委托对象。

1

如果你事先知道的DLL名称,你事先知道函数的名字,还有一个更简单的方法。

你可以简单地声明的P/Invoke签名,然后使用LoadLibrary加载例如基于配置文件项中的DLL。只要您成功地调用LoadLibrary任何P的前/调用所使用的功能,他们会取得成功的DLL已经加载。