创建线程不接受成员函数

pra*_*ran 2 c++ windows function-pointers callback

我正在尝试为网络编程创建一个类.这将创建一个带有线程的通用套接字.

但是当我尝试使用createthread()创建线程时.第三个参数是产生错误.从网上我开始知道我不能使用成员函数作为createthread()的参数.

我能做到这一点吗?

Soa*_*Box 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();
}
Run Code Online (Sandbox Code Playgroud)

CreateThread()允许您将参数传递给线程函数(CreateThread()调用的参数4).您可以使用它来传递指向您的类的指针.然后,您可以将线程存根转换为指针返回正确的类型,然后调用成员函数.你甚至可以让"myThreadStub"成为"MyClass" 的静态成员,允许它访问私有成员和数据.

如果安装了boost,则可以使用boost :: bind来执行此操作而不创建存根函数.我从来没有在Windows上试过,所以我不能肯定它会起作用(因为回调函数必须是一个WINAPI调用)但如果它确实有效,它会看起来像:

HANDLE hThread = CreateThread(NULL, 0, boost::bind(&MyClass::ThreadFunction, this), NULL, 0, &tid);
Run Code Online (Sandbox Code Playgroud)

其中thread函数是一个非静态成员函数,它接受一个void*参数.

  • Boost.Bind在这里没有帮助 - 它返回函子,而不是函数指针. (2认同)

Yev*_*iuk 5

有一个简单的方法可以解决这个问题。

看一下ThreadProc回调函数

    DWORD WINAPI ThreadProc(
      __in LPVOID lp参数
    );

现在在CreateThread 函数中:

    处理 WINAPI CreateThread(
      __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
      __in SIZE_T dwStackSize,
      __in LPTHREAD_START_ROUTINE lpStartAddress,
      __in_opt LPVOID lpParameter ,
      __在 DWORD dwCreationFlags 中,
      __out_opt LPDWORD lpThreadId
    );

使用静态方法作为线程过程,但从成员方法调用它,并将对象指针传递给它:

    #include <windows.h>

    类我的类{
     民众:
      无效CreateThreadForObject(){
        LPSECURITY_ATTRIBUTES 安全属性 = 0;
        SIZE_T 堆栈大小 = 0;
        LPTHREAD_START_ROUTINE start_routine = &MyClass::ThreadProcForObject;
        LPVOID 参数 = this;
        DWORD 创建标志 = 0;
        LPDWORD 线程_id = 0;
        CreateThread(安全属性、堆栈大小、启动例程、参数、
                     创建标志,线程id);
      }

     私人的:
      static DWORD WINAPI ThreadProcForObject( LPVOID param ) {
         MyClass* 实例 = reinterpret_cast<MyClass*>(param);
        if (!instance) 返回 1;
        // ...
        返回0;
      }
    };

抱歉,我没有足够的时间来写一个好的例子。但我想你明白这个方法。

  • 我会把这个标记为+10。这是我发现的第一个不向公众公开类内部结构的方法。我是 C# 开发人员,C# 为我做了很多有趣的事情。 (2认同)