2011-07-15 10 views
6

Voy a escribir una clase de adaptador. En esta clase hay un servidor xmlrpc-c (servidor abyss). Quiero iniciar el servidor creando un nuevo hilo, y la función del hilo es la función miembro XMLThreadFun().Cómo hacer que el miembro de la clase funcione como función de subproceso usando boost

Cuando trato de utilizar el código de abajo hay un error en la línea de implantación del constructor del adaptador:

/usr/include/boost/bind/bind.hpp:69:37: error: ‘void (Adapter::*)()’ is not a class, struct, or union type 

¿Puede alguien decirme cómo solucionar este error, o cómo lograr mi objetivo? Realmente lo aprecio.

A continuación es mi fragmento de código:

#ifdef _MSC_VER 
#pragma warning(disable : 4503 4355 4786) 
#else 
#include "config.h" 
#endif 

#include "quickfix/FileStore.h" 
#include "quickfix/SocketInitiator.h" 
#include "quickfix/SessionSettings.h" 
#include "Application.h" 
#include <string> 
#include <iostream> 
#include <fstream> 
#include "quickfix/SessionID.h" 
#include "quickfix/Session.h" 
#include "getopt-repl.h" 


#include <cassert> 
#include <xmlrpc-c/base.hpp> 
#include <xmlrpc-c/registry.hpp> 
#include <xmlrpc-c/server_abyss.hpp> 



#include <boost/thread.hpp> 
#include <boost/date_time.hpp> 

using namespace std; 
class theClient : public xmlrpc_c::method { 
public: 
    theClient() {} 
    theClient(FIX::SocketInitiator* initiator) { 
     set<FIX::SessionID> s(initiator->getSessions()); 
     set<FIX::SessionID>::iterator myIterator; 
     for (myIterator = s.begin(); myIterator != s.end(); myIterator++) { 
      string str(myIterator->getSenderCompID()); 
      clientname = str; 
     } 
    } 

    void execute(xmlrpc_c::paramList const& paramList, 
     xmlrpc_c::value * const retvalP) { 
     *retvalP = xmlrpc_c::value_string(clientname); 
    } 

private: 
    string clientname; 

}; 

class Adapter { 
private: 
    xmlrpc_c::registry myRegistry; 
    xmlrpc_c::methodPtr XMLRPCMethodP; 
    xmlrpc_c::serverAbyss webServer; 
    boost::thread webServerThread; 
public: 
    void initWebServer(string rpcHost, string rpcPort); 
    void XMLThreadFun(); 
    Adapter(string rpcHost, string rpcPort); 
}; 

Adapter::Adapter(string rpcHost, string rpcPort) : myRegistry(), XMLRPCMethodP(new theClient), webServer(myRegistry, 8181, "/tmp/xmlrpc_log"), webServerThread(boost::bind(&Adapter::XMLThreadFun, this, &webServer)) 
{ 
    initWebServer(rpcHost, rpcPort); 
} 

void Adapter::XMLThreadFun() { 
    webServer->run(); 
} 

void Adapter::initWebServer(string rpcHost, string rpcPort) { 
    webServerThread.join(); 
} 

Respuesta

8

Usted tendrá que usar boost :: bind para llamar a una función miembro como un hilo. Algo así como

class MyClass { 
public: 
    void Start(); 
    void DoStuff(int limit); 
}; 

MyClass foo; 
boost::thread thread1(boost::bind(&MyClass::Start, &foo)); 
boost::thread thread2(boost::bind(&MyClass::DoStuff, &foo, 30)); 
// threads do stuff here 
thread1.join(); 
thread2.join(); 

Específicamente aquí, parece que tendría que cambiar

webServerThread(boost::bind(&Adapter::XMLThreadFun, this, &webServer) 

a

webServerThread(boost::bind(&Adapter::XMLThreadFun, this) 
+0

En realidad, utilicé boost :: bind. Ver el final de la línea del constructor: Adapter :: Adapter (string rpcHost, string rpcPort): myRegistry(), XMLRPCMethodP (new theClient), webServer (myRegistry, 8181, "/ tmp/xmlrpc_log"), webServerThread (boost :: bind (& Adapter :: XMLThreadFun, this, & webServer)) –

+0

Ah, sus argumentos no coinciden. XMLThreadFun no toma argumentos, pero está especificando un puntero a webServer en su llamada. – Josh

5

No hay necesidad de impulsar el uso :: unen

boost::thread thread2(boost::bind(&MyClass::DoStuff, &foo, 30)); 

es equivalente a:

boost::thread thread2(&MyClass::DoStuff, &foo, 30 ); 
+2

Esto, supongo, ¿es un comentario (o complemento de) la respuesta de Josh? – jogojapan

Cuestiones relacionadas