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_thread
, receiver_thread
和serverconn_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 );
DWORD
是unsigned long
WINAPI
, WINAPI
是一个映射到__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);