【问题标题】:Calling _beginthreadx with Passing function Pointers使用传递函数指针调用 _beginthreadx
【发布时间】:2013-12-05 23:03:59
【问题描述】:

我很想知道是否可以使用未知且不基于类设计的函数指针调用 _beginthreadex。 例如:

#include <stdio.h>
#include <process.h>
#include <windows.h>

int myThread(void* data)
{
    printf("ThreadID: %d \n", GetCurrentThreadId());
    return 1;
}

HANDLE callIntThreadFunc(void (*pFunction)(LPVOID), LPVOID pvFuncArgs)
{
    //Expected to fail compilation due to __stcall
    return (HANDLE) _beginthreadex(NULL, NULL, pFunction, (LPVOID) pvFuncArgs, NULL, NULL);
}

int main(int argc, char *argv[])
{
    HANDLE hThread = callIntThreadFunc(myThread, NULL);
    WaitForSingleObject(hThread , INFINITE);

    return 0;
}

我知道 _beginthread 在转换函数时可以工作(通过以下代码):

return (HANDLE) _beginthread((void (*)(void*)) pFunction, 0, (LPVOID) pvFuncArgs);

所以我的问题是在这种情况下是否可以使用 _beginthreadex,如果可以,如何使用? 任何想法将不胜感激。

【问题讨论】:

    标签: c++ multithreading function-pointers beginthreadex


    【解决方案1】:

    未知且不基于类设计”是什么意思?一方面,_beginthreadex() 不是面向对象的 API。

    至于 known 部分,好吧:当使用函数指针时,编译器至少需要知道指向的函数在哪里(它的地址)以及如何调用它(它期望什么参数以及它返回什么值)。如果您偏离该合同,则无法保证:调用可能最终可靠或不可靠,具体取决于生成的代码。

    在您的示例中,_beginthreadex() 告诉您它需要一个使用 __stdcall 约定的函数,将地址作为参数并且不返回任何结果。您给它一个返回int 并接受地址参数的函数,但是(假设默认编译器设置)使用常规C 调用约定而不是__stdcall:因此可能会出现一些堆栈损坏。通过使用强制转换,您只是在告诉编译器停止抱怨并生成调用(无论结果如何)。

    如果您想做类似示例中的操作,给_beginthreadex() 提供一个__stdcall 函数来调用您实际想要使用的任何函数会更安全。

    【讨论】:

      【解决方案2】:

      找到了我一直在寻找的答案——正如 Lois 所说,它是可行的,而且它的转换很重要。 下面的代码使它发生,编译和传播线程;-)

      return (HANDLE) _beginthreadex(NULL, NULL,(unsigned (__stdcall*)(void*)) pFunction, pvFuncArgs, NULL, NULL);
      

      谢谢大家。

      【讨论】:

        猜你喜欢
        • 2018-07-29
        • 2014-04-07
        • 1970-01-01
        • 2019-09-16
        • 2013-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-25
        相关资源
        最近更新 更多