Как сделать функцию-член класса функцией потока, используя boost - PullRequest
6 голосов
/ 15 июля 2011

Я собираюсь написать класс адаптера. В этом классе есть сервер xmlrpc-c (сервер пропасти). Я хочу запустить сервер, создав новый поток, а функция потока - это функция-член XMLThreadFun().

Когда я пытаюсь использовать приведенный ниже код, возникает ошибка в строке реализации конструктора адаптера:

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

Может кто-нибудь сказать мне, как решить эту ошибку или как достичь моей цели? Я действительно ценю это.

Ниже приведен фрагмент кода:

#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();
}

Ответы [ 2 ]

8 голосов
/ 15 июля 2011

Вам нужно будет использовать boost :: bind для вызова функции-члена как потока.Что-то вроде

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();

В частности, здесь, похоже, вы бы изменили

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

на

webServerThread( boost::bind( &Adapter::XMLThreadFun, this )
5 голосов
/ 09 марта 2012

Нет необходимости использовать boost :: bind

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

эквивалентно:

boost::thread thread2( &MyClass::DoStuff, &foo, 30  );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...