开发者

PInvoke when you don't know the DLL at compile time?

In C#, I'm trying to PInvoke a "simple" function I have in C++. The issue is that I don't know the name or location of the library at compile time. In C++, this is easy:

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.

For the life of me I can't figure out how to do this in C#. I wouldn't have any trouble if I knew the dll name, it would look something like this:

[DllImport("someLib.dll")]
uint MyMethod(int i,
              [In, MarshalAs(UnmanagedType.Interface)] IUnknown input, 
              [Out, MarshalAs(UnmanagedType.Interface)] out IUnknown output);

How do开发者_Python百科 I do this without knowing the dll I'm loading from at compile time?


You do it the same way. Declare a delegate type whose signature matches the exported function, just like SomeFuncSig. Pinvoke LoadLibrary and GetProcAddress to get the IntPtr for the exported function, just like you did in C++. Then create the delegate object with Marshal.GetDelegateForFunctionPointer().


Thee is a solution here: Dynamically calling an unmanaged dll from .NET (C#) (based on LoadLibrary/GetProcAddress)


If you know the DLL name in advance, and you know the function names in advance, there is a simpler way.

You can simply declare the P/Invoke signatures, then use LoadLibrary to load the DLL based on for example a configuration file entry. As long as you successfully call LoadLibrary before any of the P/Invoke functions are used, they will succeed as the DLL is already loaded.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜