还有一个类似于我的问题,但我想收集一些细节:
我想创建一个从非托管代码调用的DLL。当在DLL中调用非托管函数时,我想收集信息并以某种形式显示它。
我想做的是,当调用DllMain()并且原因是 DLL_PROCESS_ATTACH 时,我想实例化一个表单。此表单应在单独的线程上运行。当我的DLL中的函数FOO()被调用时,我想从FOO()中获取信息,将其发送到表单进行渲染。
所以,更具体地说:
i) 创建DLL项目的正确方法是什么,并且能够让设计器中创建的Windows窗体可用于DLL?
ii) 为此表单提供自己的线程和消息处理循环的正确方法是什么?
iii) 如何将非托管DLL函数中的信息发送到表单,或者是可以更新自己的状态和表单的托管类? < / p>
DLL内部的表单是一种“监视器”,用于传入和传出DLL的数据,因此我可以跟踪错误/错误,但不会更改可用的DLL函数的核心功能。 / p>
答案 0 :(得分:0)
在DllMain中做事时你应该非常小心(你不能调用LoadLibrary或其他获取加载器锁的函数)
答案 1 :(得分:0)
应用程序只能有一个消息处理循环 - 所有UI必须存在于单个线程上。您可以创建一个位于应用程序UI线程上的无模式窗体,但如果UI线程“忙”,它将不会将消息分发给您的窗体,因此它不会是交互式的。
恕我直言,避免麻烦的最简单方法是编写一个单独的.exe来处理表单并让你的dll简单地启动它,以便整个表单作为一个单独的常规WinForms进程运行。然后你可以使用套接字,WM_USER消息,甚至只是共享文件从你的DLL发送命令和数据到表单的进程。 (套接字的优点是你也可以在不同的PC上运行监控表单)
答案 2 :(得分:0)
这就是我的所作所为:
static HWND *callbackWindow; struct Info instanceInfo; DLLEXPORT void setCallbackWindow(HWND* newCallbackWindow) { callbackWindow = newCallbackWindow; } DLLEXPORT void checkForInformation() { /* gather some info ... */ instanceInfo.computerOver = VERY_YES; } DLLEXPORT void retrieveInformation() { PostMessage(callbackWindow, ...); }
首先,将回调设置为Form.Handle。 Thenyou可以通过以.NET格式覆盖WndProc来调用checkForInformation(),也可以设置定时器来定期调用checkForInformation。一旦你的表单准备好信息调用retrieveInformation()并在Form的窗口处理程序中检查一个魔术消息(WM_USER +你的偏移量)。