Calling _beginthreadx with Passing function Pointers

430 views Asked by At

I'm interested to know if it is possible to call _beginthreadex with function pointer that is not known and NOT based on class design. For example:

#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;
}

I'm aware that _beginthread can work when converting the function (by the following code):

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

So my question is if it possible to use _beginthreadex in such cases and if so how? Any thoughts will be appreciated.

2

There are 2 answers

0
user3072297 On BEST ANSWER

Found the answer i was looking for - it is doable and its conversion matter as Lois said. The following code make it happen, compile and spread the thread ;-)

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

Thanks all.

0
Luis On

What do you mean by "not known and NOT based on class design"? For one, _beginthreadex() is not an object-oriented API.

As to the known part, well: when using a function pointer the compiler will at least need to know where the pointed function is (its address) and how to call it (what parameters it expects and what values it returns). If you deviate from that contract, nothing is guaranteed: the call might end up working reliably or not depending on the generated code.

In your example, _beginthreadex() is telling you that it expects a function that uses the __stdcall convention, takes an address as a parameter and returns no results. You're giving it a function that returns an int and takes an address parameter but (assuming default compiler settings) uses the regular C calling convention instead of __stdcall: therefore some stack corruption is likely. By using the cast, you're just telling the compiler to stop complaining and generate the call (whatever the consequences).

If you want to do something like in your example, it's safer to give _beginthreadex() a __stdcall function that calls whatever function you actually want to use.