我正在尝试为网络编程创建一个类。这将创建一个带有线程的通用套接字。
但是当我尝试使用createthread()创建线程时。第三个参数是产生错误。从网上我开始知道我不能使用成员函数作为createthread()的参数。
有什么方法可以实现这个目标吗?
答案 0 :(得分:16)
处理此问题的最简单方法是创建一个“存根”函数,该函数将回调到您的类中。
UINT tid
HANDLE hThread = CreateThread(NULL, 0, myThreadStub, this, 0, &tid);
....
unsigned long WINAPI myThreadStub(void *ptr)
{
if (!ptr) return -1;
return ((MyClass*)ptr)->ThreadMain();
}
CreateThread()允许您将参数传递给线程函数(CreateThread()调用的参数4)。您可以使用它来传递指向您的类的指针。然后,您可以将线程存根转换为指针返回正确的类型,然后调用成员函数。你甚至可以让“myThreadStub”成为“MyClass”的 static 成员,允许它 访问私人会员和数据。
如果安装了boost,则可以使用boost :: bind来执行此操作而不创建存根函数。我从来没有在Windows上尝试过,所以我不能肯定它会起作用(因为回调函数必须是一个WINAPI调用)但如果它确实有效,它看起来像:
HANDLE hThread = CreateThread(NULL, 0, boost::bind(&MyClass::ThreadFunction, this), NULL, 0, &tid);
其中thread函数是一个非静态成员函数,它接受一个void *参数。
答案 1 :(得分:3)
有一种简单的方法可以解决问题。
看看ThreadProc callback function:
DWORD WINAPI ThreadProc( __in LPVOID lpParameter );
HANDLE WINAPI CreateThread( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId );
使用静态方法作为线程过程,但是从成员方法调用它,并将对象指针传递给它:
#include <windows.h> class MyClass { public: void CreateThreadForObject() { LPSECURITY_ATTRIBUTES security_attributes = 0; SIZE_T stack_size = 0; LPTHREAD_START_ROUTINE start_routine = &MyClass::ThreadProcForObject; LPVOID param = this; DWORD creation_flags = 0; LPDWORD thread_id = 0; CreateThread(security_attributes, stack_size, start_routine, param, creation_flags, thread_id); } private: static DWORD WINAPI ThreadProcForObject(LPVOID param) { MyClass* instance = reinterpret_cast<MyClass*>(param); if (!instance) return 1; // ... return 0; } };
抱歉,我没有足够的时间写一个好例子。但我认为你理解这种方式。
答案 2 :(得分:-1)