CreateThread中的转换错误

当我尝试使用CreateThread函数时,我有一个奇怪的错误。 这是我的代码:

 HANDLE threads[3]; //threads[0] is printer, threads[1] is receiver, [2] is serverconn DWORD printer_id, receiver_id, serverconn_id; if( ((threads [0] = CreateThread(NULL, 0, printer_thread, (LPVOID) thread_args, 0, &printer_id)) == NULL) || ((recv_thread = threads [1] = CreateThread(NULL, 0, receiver_thread, (LPVOID) thread_args, 0, &receiver_id)) == NULL) || ((threads [2] = CreateThread(NULL, 0, serverconn_thread, (LPVOID) thread_args, 0, &serverconn_id)) == NULL) ) { IO_print_line("Initialization error"); return FALSE; } 

printer_threadreceiver_threadserverconn_thread是这样定义的函数:

int serverconn_thread(LPVOID args);

Visual Studio编译器给我这个错误:

 Error C2440 'function': cannot convert from 'int (__cdecl *)(LPVOID)' to 'LPTHREAD_START_ROUTINE' 

我真的不明白,因为我认为我完全按照官方文档的建议完成了 。

不,将线程函数的返回类型更改为DWORD并不能解决任何问题,错误只会更改为:

 Error C2440 'function': cannot convert from 'DWORD (__cdecl *)(LPVOID)' to 'LPTHREAD_START_ROUTINE' 

奇怪的是,如果我改变它:

 if( ((threads [0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) &printer_thread, (LPVOID) thread_args, 0, &printer_id)) == NULL) || ((recv_thread = threads [1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) &receiver_thread, (LPVOID) thread_args, 0, &receiver_id)) == NULL) || ((threads [2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) &serverconn_thread, (LPVOID) thread_args, 0, &serverconn_id)) == NULL) ) 

使用强制转换,编译器是可以的,但我不认为以这种方式强制执行它是一个好主意。 我该如何解决?

在声明线程函数时,您没有遵循官方文档 。

您的原始声明使用int作为返回值,并使用__cdecl (隐式)作为调用约定。 将返回值更改为DWORD ,未更改调用约定。

但是, 文档清楚地显示了正确的声明:

 DWORD WINAPI ThreadProc(
   _In_ LPVOID lpParameter
 );

DWORDunsigned long WINAPIWINAPI是一个映射到__stdcall调用约定的宏(请参阅Windows数据类型 )。

因此,正确声明您的function将是:

 unsigned long __stdcall printer_thread(void *args); unsigned long __stdcall receiver_thread(void *args); unsigned long __stdcall serverconn_thread(void *args); 

但是,由于CreateThread()LPTHREAD_START_ROUTINE作为输入(声明为DWORD (WINAPI*)(LPVOID) (请参阅winbase.h的实际声明)),因此应声明要匹配的函数:

 DWORD WINAPI printer_thread(LPVOID args); DWORD WINAPI receiver_thread(LPVOID args); DWORD WINAPI serverconn_thread(LPVOID args);