我正在尝试使用QueueUserAPC
在特定线程上异步运行某些函数。编译为x64时,我的代码工作正常,但是当我编译并运行x86时,我得到访问冲突。
在我的帖子的最后是一个最小的,完整的例子,显示了我想要做的事情(为了简洁省略了线程和事件的清理)。
在我的机器上,当我编译并运行“x64”时,我得到了预期的输出:
等候...
异步功能!
等候...
异步功能!
等候...
ConsoleApplication3.exe(进程17100)退出,代码为0。
当我编译并运行“x86”时,我得到:
等候...
异步功能!
然后是访问冲突,这里:
if (WaitForSingleObjectEx(param, INFINITE, TRUE) == WAIT_OBJECT_0)
ConsoleApplication3.exe中的0x776227FB(ntdll.dll)抛出异常:0xC0000005:访问冲突读取位置0x36623194。
我究竟做错了什么?
完整示例:
#include "pch.h"
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
DWORD ThreadFunction(LPVOID param)
{
while (true)
{
printf("waiting...\n");
if (WaitForSingleObjectEx(param, INFINITE, TRUE) == WAIT_OBJECT_0)
break;
}
ExitThread(0);
return 0;
}
void AsyncFunction(UINT_PTR param)
{
printf("async function!\n");
}
int main()
{
HANDLE hThread, hStopEvent;
DWORD threadID;
hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFunction, hStopEvent, 0, &threadID);
Sleep(1000);
QueueUserAPC((PAPCFUNC) AsyncFunction, hThread, NULL);
Sleep(1000);
QueueUserAPC((PAPCFUNC) AsyncFunction, hThread, NULL);
Sleep(1000);
SetEvent(hStopEvent);
WaitForSingleObject(hThread, INFINITE);
}
我的AsyncFunction
定义有两个错误:
1 - 参数类型应为ULONG_PTR
,而不是UINT_PTR
。这实际上是我真实实现中的复制粘贴错误
2 - 缺少函数的调用约定
void AsyncFunction(UINT_PTR param)
应该是void CALLBACK AsyncFunction(ULONG_PTR param)
然后在这里没有必要演员到PAPCFUNC
:
QueueUserAPC((PAPCFUNC) AsyncFunction, hThread, NULL);