Search code examples
cwinapicreatethread

How to call custom callback function in CreateThread?


I want to use CreateThread function but with my own custom callback function, this is how I am using it

 HANDLE handle = CreateThread(0,0,custom_function, NULL,0,NULL);

declaration of custom_function

DWORD custom_function(void)
{
    printf("Hello from callback function");
}

the warning I get

main.c:154:37: warning: passing argument 3 of 'CreateThread' from incompatible pointer type [-Wincompatible-pointer-types]    
  154 |         handle = CreateThread(0, 0, custom_function, NULL, 0, NULL);
      |                                     ^~~~~~~~~~~
      |                                     |
      |                                     DWORD (*)(void) {aka long unsigned int (*)(void)}
In file included from C:/msys64/mingw64/include/winbase.h:29,
                 from C:/msys64/mingw64/include/windows.h:70,
                 from rce.c:3:
C:/msys64/mingw64/include/processthreadsapi.h:279:127: note: expected 'LPTHREAD_START_ROUTINE' {aka 'long unsigned int (*)(void *)'} but argument is of type 'DWORD (*)(void)' {aka 'long unsigned int (*)(void)'}
  279 |   WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
      |                                                                                                        ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~

Solution

  • What the warning is telling you is that the parameter to the callback function needs to be a void* (or LPVOID if using Windows API types).

    If POSIX threads are familiar, this is not so different - CreateThread allows you to pass a void pointer to custom data as parameter to the callback. But you don't have to use it.

    The callback should correctly be written as:

    DWORD WINAPI custom_function (LPVOID lpParam);
    

    WINAPI specifies that __stdcall calling convention should be used. This might be required since this function is to be called from the OS and not from your C program (which probably uses __cdecl calling convention).

    As for executing, please note that CreateThread gives you the option to create the thread suspended (asleep) or running.