0
votes

How to bind a class member function (without input arguments) with an object of the class so that the binded function can be used to create a thread by pthreads?

#include <tr1/functional>
  using std::tr1::bind;
using namespace std::tr1::placeholders;


Server server(port_number);
Server* serverPtr;
serverPtr = &server; 

pthread_t my_thread = makeThread(bind(&lab1::Server::Run), serverPtr);

pthread_t makeThread(ThreadBody body) {

ThreadBody* copy = new ThreadBody(body);

void* arg = reinterpret_cast<void*>(copy);
pthread_t thread;
if (pthread_create(&thread, NULL, threadFunction, arg) != 0) {
perror("Can't create thread");
delete copy;
exit(1);
 }
return thread;
}

I got compile error:

I have no idea what this error means.

/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h: In instantiation of âstd::tr1::_Result_of_implâ:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional:126: instantiated from âstd::tr1::result_ofâ
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/bind_iterate.h:44: instantiated from âstd::tr1::_Bindâ
lab2.cpp:80: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:106: error: âintâ is not a class, struct, or union type
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h: In instantiation of âstd::tr1::_Result_of_implâ:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional:126: instantiated from âstd::tr1::result_ofâ
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/bind_iterate.h:55: instantiated from âstd::tr1::_Bindâ
lab2.cpp:80: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:106: error: âconst intâ is not a class, struct, or union type
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h: In instantiation of âstd::tr1::_Result_of_implâ:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional:126: instantiated from âstd::tr1::result_ofâ
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/bind_iterate.h:66: instantiated from âstd::tr1::_Bindâ
lab2.cpp:80: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:106: error: âvolatile intâ is not a class, struct, or union type
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h: In instantiation of âstd::tr1::_Result_of_implâ:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional:126: instantiated from âstd::tr1::result_ofâ
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/bind_iterate.h:77: instantiated from âstd::tr1::_Bindâ
lab2.cpp:80: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:106: error: âconst volatile intâ is not a class, struct, or union type
lab2.cpp: In constructor âlab1::Server::Server(int)â:
lab2.cpp:80: error: could not convert âstd::tr1::bind [with _Functor = int, _T1 = sockaddr*, _T2 = long unsigned int](((lab1::Server*)this)->lab1::Server::listen_fd_, ((sockaddr*)(& server_endpoint)), 16ul)â to âboolâ
thread.hpp: In function âint main(int, char**)â:
thread.hpp:34: error: too many arguments to function âpthread_t base::makeThread(base::ThreadBody)â
lab2.cpp:229: error: at this point in file
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/bind_iterate.h: In member function âtypename std::tr1::result_of::type std::tr1::_Bind:perator()() [with _Functor = std::tr1::_Mem_fn]â:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:502: instantiated from âstatic void std::tr1::_Function_handler::_M_invoke(const std::tr1::_Any_data&) [with _Functor = std::tr1::_Bind ()()>]â
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:850: instantiated from âstd::tr1::function::function(_Functor, typename std::__enable_if::_Useless, (! std::tr1::is_integral::value)>::__type) [with _Functor = std::tr1::_Bind ()()>, _Res = void]â
lab2.cpp:229: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/bind_iterate.h:45: error: no match for call to â(std::tr1::_Mem_fn) ()â
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:207: note: candidates are: _Res std::tr1::_Mem_fn:perator()(_Class&) const [with _Res = void, _Class = lab1::Server]
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/functional_iterate.h:213: note: _Res std::tr1::_Mem_fn:perator()(_Class*) const [with _Res = void, _Class = lab1::Server]
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/bind_iterate.h:45: error: return-statement with a value, in function returning 'void'
make: *** [lab2_server] Error 1
1

1 Answers

1
votes

You should use bind like this

bind(&lab1::Server::Run, serverPtr);

But i think pthread_create doesn't accept a function returned by bind. You can write a static helper method in Server and use the arg argument.

class Server
{
  static void RunWrapper(void* server)
  {
     Server* s = static_cast<Server*>(server);
     s->Run();
  }
};


Server* myServer = CreateServer();
pthread_create(&thread, NULL, &Server::RunWrapper, myServer);