2014-02-12 73 views
1

我在做一个发送短信程序,但是当我在线程中创建与服务器的连接时,我得到一个错误。在C++中创建线程时出错

g++ -L/usr/lib/i386-linux-gnu -o main Socket.cpp ServerSocket.cpp modemSMS_w.cpp main.cpp Config.cpp -lpthread -lserial -lxml2 -lmysqlclient 
modemSMS_w.cpp: In member function ‘void modem::enviasms()’: 
modemSMS_w.cpp:96:77: error: cannot convert ‘void* (modem::*)(void*)’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’ 

程序:

#include "modemSMS_w.hpp" 
#define CTRL_C "\x1A" 

using namespace LibSerial; 
using namespace std; 

modem::modem() 
{ 
} 

void *modem::func_servidor(void *ptr) 
{ 

ServerSocket server(30001); 

     try { 
       ServerSocket new_sock; 
       while(1) 
       { 
         server.accept(new_sock); 
         cout << "Conexao aceita" << endl; 
       } 
     } 
     catch (SocketException& e) { 
       cout << "Erro: Criando Servidor" << endl; 
     } 

} 

int modem::setSerial() { 
..... 
.... 
... 
} 

void modem::enviasms(){ 

    pthread_t thread_servidor; 
    pthread_cond_t cv; 

    const int PORT_MON = 30000; 
    string serialPort = "/dev/ttyS0"; 

    int argc; 
    int ret; 
    char **argv; 

    cout << "\n------------------------\n MODEM GPRS \n------------------------" << endl; 
    string mensagem ="Conversao"; 
    mensagem.c_str(); 

    ret = pthread_cond_init(&cv, NULL); 
    bool envia = true; 
    envia = true; 
    if (ret != 0) 
    { 
      cout << "Erro na criação do evento. Por favor reeinicie o programa." << endl; 
    } 

    //ERROR IN THIS LINE 
    pthread_create(&thread_servidor, NULL,&modem::func_servidor, (void*) true); 

    Config config; 
    SerialStream ssStream; 
    setSerial(); 

.... 
... 
} 

对不起,不知道几乎没有在C++中创建线程已经试图解决这个问题,但是没有sucess。

+2

不知道你为什么要使用pthread_create原语来实现这样的基本用法,但是如果你使用的是现代C++编译器,最好使用'std :: thread'(或'boost:thread')。另外,对于你的问题,你传递一个指向一个成员函数的指针,指向一个自由函数的指针。那些不一样。 – ereOn

+0

[如何从成员函数中获取“简单”函数指针]的可能重复(http://stackoverflow.com/questions/15958553/how-to-get-a-simple-function-pointer-from-a-成员函数) –

回答

1

您可以添加静态函数的类,并在在pthread_create函数中使用它:

class modem { 
    public: 
     //... 
     static void* thread_func(void* arg); 
     //... 
}; 

void* modem::thread_func(void* arg) { 
    return reinterpret_cast<modem*>(arg)->func_servidor(); 
} 

void *modem::func_servidor() { 
    // some code 
} 

void modem::enviasms(){ 
    //some code scipped 
    if(pthread_create(&thread_servidor, NULL, &modem::thread_func, reinterpret_cast<void*>(this)) != 0) { 
     //some error handling code 
    } 
    //... 
    if(pthread_join(thread_servidor, NULL) != 0) { 
    // handle error 
    } 
} 

但是,恕我直言,这是更好的使用升压或std线程。你不需要静态函数使用这种方法:

auto thr = std::thread{ &modem::func_servidor, this }; 
//... 
thr.join(); 

但请注意,你必须检查的对象,当你线程的存在是为了将存在this点。

+0

我会试试这个 – Neto

+0

@Neto要小心 - 线程存在时'this'指针必须有效。如果调制解调器对象被销毁并且线程仍然存在,您将会遇到未定义的行为。 –

+0

它工作得很好......我不得不做一些改变,但是你帮了我很多人...... thx! – Neto

1

你永远不会创建你的Modem类的实例,那么如何调用该类的成员函数呢?

会员功能需要会员才能操作。不要将指针指向成员函数pthread_create。创建一个调用成员函数的非成员函数,并将指向它的指针传递给pthread_create

+0

即时通讯从C到C++,所以我不知道几乎没有关于类...我怎样才能创建这个非成员函数并传递一个指针,该pthread_create? – Neto

+1

@Neto我会强烈要求你忘记线程,直到你理解了C++的基础知识。当你试图一次完成所有这些问题时,你永远不会将这些问题排除在外。如果“你不能调用一个没有类成员的非静态类成员函数”对你来说并不明显,或者你不知道这个“this”指针是什么,那么你就没有业务与线程和类混淆了同一时间。 –

+0

是的,我已经在学习了,但我没有太多的耐心。为我的无知服务 – Neto