我正在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);
在这个问题中,我发现使用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);
如您所见,您不再需要静态成员函数.