x86 上的 QueueUserAPC 访问冲突
QueueUserAPC access violation on x86
我正在尝试使用 QueueUserAPC
到 运行 某些特定线程上的异步函数。我的代码在为 x64 编译时工作正常,但是当我为 x86 编译并 运行 时,我遇到了访问冲突。
在我的 post 结尾是一个最小的完整示例,展示了我正在尝试做的事情(为简洁起见,线程和事件的清理被省略)。
在我的机器上,当我为“x64”编译并 运行 时,我得到了预期的输出:
waiting...
async function!
waiting...
async function!
waiting...
ConsoleApplication3.exe (process 17100) exited with code 0.
当我为“x86”编译并 运行 时,我得到:
waiting...
async function!
然后是访问冲突,这里:
if (WaitForSingleObjectEx(param, INFINITE, TRUE) == WAIT_OBJECT_0)
Exception thrown at 0x776227FB (ntdll.dll) in ConsoleApplication3.exe: 0xC0000005: Access violation reading location 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);
我正在尝试使用 QueueUserAPC
到 运行 某些特定线程上的异步函数。我的代码在为 x64 编译时工作正常,但是当我为 x86 编译并 运行 时,我遇到了访问冲突。
在我的 post 结尾是一个最小的完整示例,展示了我正在尝试做的事情(为简洁起见,线程和事件的清理被省略)。
在我的机器上,当我为“x64”编译并 运行 时,我得到了预期的输出:
waiting...
async function!
waiting...
async function!
waiting...
ConsoleApplication3.exe (process 17100) exited with code 0.
当我为“x86”编译并 运行 时,我得到:
waiting...
async function!
然后是访问冲突,这里:
if (WaitForSingleObjectEx(param, INFINITE, TRUE) == WAIT_OBJECT_0)
Exception thrown at 0x776227FB (ntdll.dll) in ConsoleApplication3.exe: 0xC0000005: Access violation reading location 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);