1

我很想知道是否可以使用未知且不基于类设计的函数指针调用 _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,如果可以,如何使用?任何想法将不胜感激。

4

2 回答 2

1

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

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

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

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

于 2013-12-05T23:42:38.603 回答
0

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

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

谢谢大家。

于 2013-12-08T20:39:56.000 回答