【问题标题】:DLL crashes app after reuse重用后 DLL 使应用程序崩溃
【发布时间】:2012-10-31 07:55:18
【问题描述】:

我使用了一个使用 mdi 的应用程序,并且脚本可以附加到 mdi 窗口或从 mdi 窗口分离,以便按需运行/停止;这个脚本加载我的 dll 做一些工作;这样做很好;但是,当我分离脚本时,一切都很好,应用程序应该卸载 dll(并使用适当的 thread_attach/detach 和 process_attach/detach 操作调用 dllmain)。现在,如果我尝试将脚本重新附加到 winow,或将其附加到另一个窗口,在 dll 已使用一次之后 - 主应用程序崩溃。我已将问题隔离到由 dll 创建的线程;踏板打开了一扇窗户;所以,我像这样创建线程:

if (!hThread) hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);

并且,当脚本被分离时,它会像这样关闭线程(无论注释掉的行是否未被注释掉):

SendMessage(hWnd, WM_DESTROY, 0, 0);
//TerminateThread(hThread, 0);
//WaitForSingleObject(hWndThread, INFINITE);
CloseHandle(hThread);
hThread = NULL;

我不知道为什么主应用程序崩溃了。一个不同的线程(即一个简单地休眠一秒钟并循环的线程,不会造成任何伤害。什么给出了?

【问题讨论】:

  • @Hans Passant 感谢您查看我的问题。不幸的是,发送 WM_CLOSE 或调用 DestroyWindow 并不能解决问题。
  • 好吧,我们都知道你做错了,但我们仍然不知道崩溃是什么样子。至少发布崩溃原因和调用堆栈的内容。还要在“输出”窗口中查看任何第一次机会异常通知。
  • @Hans 我无法控制主机应用程序;我贡献的只是脚本和它使用的 DLL。由于应用程序崩溃,没有反馈:D 据我所知,我正在销毁我应该销毁的所有数据。没有线索。

标签: c++ c winapi dll crash


【解决方案1】:

好的,这里有一些想法: 你说你的线程打开一个窗口。您是在线程函数中运行消息循环,还是希望您的窗口由其他消息循环提供服务? 如果您在线程中运行自己的消息循环,则退出循环可能会发生也可能不会发生,具体取决于您编写它的方式。如果你使用类似的东西:

while(GetMessage(&msg, ...) // msg loop in the thread function
{
  .... 
}
DestroyWindow(hWnd);  // see comment below

那么这需要 WM_QUIT 而不是 WM_DESTROY 才能退出。无论如何,最好的方法是向您的窗口发送 WM_QUIT 并在退出消息循环后调用 DestroyWindow() 以正确销毁它。 引用 MSDN:

销毁窗口函数 销毁指定的窗口。该函数向窗口发送 WM_DESTROY 和 WM_NCDESTROY 消息以将其停用并从中移除键盘焦点。该函数还销毁窗口的菜单,刷新线程消息队列,销毁计时器,删除剪贴板所有权,并中断剪贴板查看器链(如果窗口位于查看器链的顶部)

在您的窗口发布 WM_QUIT 消息后,您的主线程应该等待窗口线程退出。以下是一些相关代码:

SendMessage(hWnd, WM_QUIT, 0, 0);  // send your quit message to exit the msg loop
if (WaitForSingleObject(hThread, 5000) != WAIT_OBJECT_0) // wait up to 5 seconds
{
    TerminateThread(hThread, -1); // bad! try to never end here
}

我希望这会有所帮助。我在使用窗口显示日志消息的线程日志查看器中使用它。

【讨论】:

  • 编辑:“销毁窗口后”应改为:“将 WM_QUIT 消息发布到窗口后。
  • 感谢您的建议。我确实运行了一个消息循环。但是,通常我手动关闭窗口(通过关闭按钮),因此窗口将通过 postquitmessage 接收 wm_quit。尽管如此,我还是用 wm_close 消息做了一个额外的 sendmessage。我想我已经尝试了所有的组合,但仍然没有运气。无论如何,这不再是一个紧迫的问题,因为现在代码可以工作了;仅在调试/设计时才麻烦,因为每次我必须更改代码时,我还必须重新启动托管应用程序(它本身必须重新连接到远程服务器)。无论如何,再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
相关资源
最近更新 更多