c++ - Qt4.8中使用C创建新线程

标签 c++ c linux qt pthreads

我正在Ubuntu 12.10上开发一个简单的即时通讯软件,它的客户端需要GUI。
在客户端的主窗口中,我需要创建一个线程来保持监听从服务器接收到的消息。


这是错误信息:

main.cpp:-1: In function 'int main(int, char**)':
main.cpp:27: error: invalid conversion from 'void*' to 'void* (*)(void*)' [-fpermissive]

 /usr/include/pthread.h:225: error:   initializing argument 3 of 'int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)' [-fpermissive]

maininterface.h中:

Class MainInterface: public QWidget
{
public:
    explicit MainInterface(QWidget *parent = 0);
    ~MainInterface();
    void* ServerMSGWatch(void *threadArgs=NULL); // function run in the new thread

};

它在maininterface.cpp中的定义是:

void* MainInterface::ServerMSGWatch(void *threadArgs)
{
    pthread_detach(pthread_self());
    char arrServerMSGRecv[SERVER_MSG_MAX_SIZE + 1];
    while(1){
        recv(Login::sockClnt, arrServerMSGRecv, SERVER_MSG_MAX_SIZE+1, 0);
        Handle_Server_MSG(arrServerMSGRecv); 
        memset(arrServerMSGRecv, 0, SERVER_MSG_MAX_SIZE+1);
    }
    return NULL;
}

main.cpp 中:

MainInterface mWindow;
mWindow.show();
pthread_t pthreadID;
pthread_create(&pthreadID, NULL, mWindow.ServerMSGWatch(), NULL); 

在这个question ,我发现使用 C++ 编译器编译 c 代码可能有问题。

所以我尝试添加一个“c_pthread.h”:

#ifndef C_PTHREAD_H
#define C_PTHREAD_H

#ifdef  __cplusplus

extern "C" {

#endif

void* ServerMSGWatch(void *threadArgs=NULL);
void Handle_Server_MSG(char *arrServerMSGRecv);

#ifdef  __cplusplus

}
#endif
#endif // C_PTHREAD_H

c_pthread.cpp:

void* ServerMSGWatch(void *threadArgs=NULL)
{
     //definition
}

void Handle_Server_MSG(char *arrServerMSGRecv)
{
    //definition
}

然后在main.cpp中调用它:

#include "c_pthread.h"
pthread_t pthreadID;
pthread_create(&pthreadID, NULL, ServerMSGWatch(), NULL); 

但我仍然遇到同样的错误。


PS:对一些不恰当的行为感到抱歉。

最佳答案

您有两个问题:第一个是您调用函数而不是传递它。另一个更微妙的是,您不能将非静态类成员函数用作线程函数。

最后一个问题的原因是因为非静态成员函数有一个隐藏的第一个参数,即 this 指针。

在这种情况下,您可以通过添加一个static 成员函数来解决它,并将指向该对象的指针作为参数传递给线程函数。然后静态函数调用对象中的实际函数:

class MainInterface: public QWidget
{
public:
    ...

    static void* StaticServerMSGWatch(void* arg)
    {
        reinterpret_cast<MainInterface*>(arg)->ServerMSGWatch();
        return nullptr;
    }

    void ServerMSGWatch(); // function run in the new thread
};

...

pthread_create(&pthreadID, NULL, &MainInterface::StaticServerMSGWatch, &mWindow);

如果你有支持 C++11 的编译器和库,你可以使用 std::thread相反:

std::thread myThread(&MainInterface::ServerMSGWatch, &mWindow);

如您所见,您不再需要静态成员函数。

关于c++ - Qt4.8中使用C创建新线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20397675/

相关文章:

在 C/C++ 中创建库 - ld 找不到我的库

linux - 在 Vim 中有复制括号内文本的好方法吗?

linux - Python3 mlpy 安装错误 - ‘Py_InitModule3’ 未在此范围内声明

c++ - C++程序打印到哪里?

c++ - 在运行时检测 C++ 中的堆碎片的可移植方法?

c++ - 如何编写用于从 C 访问 C++ 类成员的包装器(具有继承和构造函数)

c - 如何安全使用Linux新功能?

linux - pg_statsinfo-10.0-1.pg10.rhel7.x86_64 需要错误 : Failed dependencies: libpq. so.5()(64bit)

c++ - 从文本文件创建二维字符串 vector

c++ - 为类提供类似元组的结构化绑定(bind)访问