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);