DLLImport a variable MFC dll

Posted

技术标签:

【中文标题】DLLImport a variable MFC dll【英文标题】: 【发布时间】:2013-01-31 14:32:53 【问题描述】:

于是我创建了以下测试项目:

[DllImportAttribute("TestMFCDLL.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int test(int number);

private void button1_Click(object sender, EventArgs e)

    int x = test(5);

这对于我定义了函数测试的 MFC dll 来说工作得很好,但是我实际上拥有的是许多 MFC dll,它们都共享一个共同的入口函数并根据我的输入以不同的方式运行。所以基本上我有大量的 dll,我在编译时不知道它的名字是什么,我只知道它们具有类似于这个程序的设置方式的功能,有没有办法根据运行时知识导入 dll?简单地这样做会返回一个错误:

static string myDLLName = "TestMFCDLL.dll";
[DllImportAttribute(myDLLName, CallingConvention = CallingConvention.Cdecl)]

属性参数必须是常量表达式,typeof 表达式 或属性参数类型的数组创建表达式

【问题讨论】:

Dynamically P/Invoking a DLL的可能重复 【参考方案1】:

如果您想动态加载 DLL 并使用 DLL 中的函数,那么您需要做更多的事情。首先,您需要动态加载 DLL。为此,您可以使用 LoadLibrary 和 FreeLibrary。

[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllName);

[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);

其次需要获取DLL中函数的地址并调用。

[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string functionName);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int Test(int number);

综合起来:

IntPtr pLib = LoadLibrary(@"PathToYourDll.DLL");
IntPtr pAddress = GetProcAddress(pLib, "test");
Test test = (Test)Marshal.GetDelegateForFunctionPointer(pAddress, typeof(Test));
int iRresult = test(0);
bool bResult = FreeLibrary(pLib);

【讨论】:

完美,我实际上按照你的回答让它正常工作,但我没有包括可能很重要的 FreeLibrary。感谢您的解决方案! 如果你不调用 FreeLibrary,那么这个库将被保存在内存中。因此,如果您有一个循环遍历一堆 DLL,加载它们,调用 test 并且不调用 FreeLibrary,那么所有 DLL 都将保存在内存中,并且您可能会耗尽内存。如果您的程序只需要在启动时加载一个 DLL 并在终止时释放它,您也可以省略 FreeLibrary。当然,我更愿意进行适当的清理。

以上是关于DLLImport a variable MFC dll的主要内容,如果未能解决你的问题,请参考以下文章

MFC ResumeThread 和 std::condition_variable 等待后偶尔线程同步失败

非 MFC 应用程序中的 MFC 对话框

《深入浅出MFC》第六章 MFC程序的生死因果

MFC 对话框的事件处理

MFC:Win32-Dll及MFC-Dll编写调用

error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall CADOConn::C