x86上的QueueUserAPC访问冲突

时间:2019-03-21 02:33:45

标签: multithreading winapi access-violation

我正在尝试使用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);
}

1 个答案:

答案 0 :(得分:2)

我的AsyncFunction定义有两个错误:

1-参数类型应为ULONG_PTR,而不是 UINT_PTR。这实际上是我实际实施中的复制粘贴错误

2-函数缺少调用约定

void AsyncFunction(UINT_PTR param)应该是void CALLBACK AsyncFunction(ULONG_PTR param)

然后就无需在此处强制转换为PAPCFUNC

QueueUserAPC((PAPCFUNC) AsyncFunction, hThread, NULL);