【发布时间】:2014-08-27 22:57:23
【问题描述】:
我用Visual C++ 2008写了一个DLL MyDLL.dll,如下:
(1) MFC 静态链接 (2) 使用多线程运行库。
在DLL中,这是两个导出函数共享的全局数据m_Data,如下:
ULONGLONG WINAPI MyFun1(LPVOID *lpCallbackFun1)
{
...
Write m_Data(using Critical section to protect)
…
return xxx;
}
ULONGLONG WINAPI MyFun2(LPVOID *lpCallbackFun2)
{
...
Suspend MyThread1 to prevent conflict.
Read m_Data(using Critical section to protect)
Resume MyThread1.
…
return xxx;
}
在我的主应用程序中,它会先调用LoadLibrary来加载MyDLL.dll,然后获取MyFun1和MyFun2的地址,然后做如下事情:
(1) 启动一个新线程MyThread1,它会调用MyFun1来做一个耗时的任务。 (2) 启动一个新线程MyThread2,会多次调用MyFun2,如下:
for (nIndex = 0; nIndex = 20; nIndex)
{
nResult2 = MyFun2(lpCallbackFun2);
NextStatement2;
}
虽然 MyThread1 和 MyThread2 使用临界区来保护共享数据 m_Data,但我仍然会在访问共享数据之前暂停 MyThread1,以防止任何可能的冲突。
问题是:
(1) MyFun2第一次调用时,一切正常,MyFun2(即nResult2)的返回值为1,符合预期。 (2) MyFun2第二、三、四次invoke时,MyFun2中的操作执行成功,但MyFun2(即nResult2)的返回值是随机值,而不是期望值1。我尝试使用Debug来跟踪到 MyFun2,并确认最后一个 return 语句只是返回一个值 1,但是调用者在检查 nResult2 时将收到一个随机值而不是 1。 (3) MyFun2 第四次调用后返回 MyFun2 后面的下一条语句,无论下一条语句是什么,我总是会得到“buffer overrun detected”的错误。
我认为这看起来像是堆栈损坏,因此请尝试进行一些测试:
- 我确认编译器中的 /GS(堆栈安全检查)功能已开启。
- 如果在 MyThread1 中的 MyFun1 完成后调用 MyFun2,则一切正常。
- 在调试模式下,MyFun2 中读取共享数据 m_Data 的代码行不会导致任何错误或异常。 MyFun1 中写入共享数据的代码行也不会。
那么,如何解决这个问题
谢谢!
【问题讨论】:
-
我不知道您的问题,可能是您未显示的大型代码中的一个无关问题。但是请不要暂停其他线程,那将导致灾难! 临界区将在需要时停止和恢复线程,前提是它们被正确使用。
-
你使用
SuspendThread()函数吗? -
问题解决了,我获取到函数地址后,缺少WINAPI修饰符。
标签: c++ multithreading dll mfc