【问题标题】:PInvoke when you don't know the DLL at compile time?在编译时不知道 DLL 时 PInvoke?
【发布时间】:2012-03-27 17:18:58
【问题描述】:

在 C# 中,我试图 PInvoke 我在 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 名称,我不会有任何麻烦,它看起来像这样 something

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

如何在不知道编译时加载的 dll 的情况下执行此操作?

【问题讨论】:

    标签: c# pinvoke


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      你是一个解决方案:Dynamically calling an unmanaged dll from .NET (C#)(基于 LoadLibrary/GetProcAddress)

      【讨论】:

      • 我错过了什么吗?要使用 LoadLibrary,您确实需要知道 dll 的名称。如果 OP 知道 dll 的名称,他将不会首先尝试找到不同的解决方案。编辑:认为我错过了“在编译时”与“在运行时”。
      【解决方案3】:

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

      您可以简单地声明 P/Invoke 签名,然后使用 LoadLibrary 根据配置文件条目加载 DLL。只要您成功调用LoadLibrary使用任何 P/Invoke 函数,它们就会成功,因为 DLL 已经加载。

      【讨论】:

        猜你喜欢
        • 2012-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 2017-06-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多