0

Trying to write some simple multithreaded server program and got that error recently:

Server.cpp:64:64: error: argument of type ‘void* (Server::)(void*)’ does not match ‘void* (*)(void*)

Here is some lines from my code:

Header file:

class Server
{
public:
void establishConnection(const char * );
...

private:
void *listening(void *);
void *acceptingConnection(void *);
pthread_attr_t attrr;
}

cpp file:

void Server:: establishConnection(const char *port_number )
{
...
  pthread_create(&listn, &attrr, Server::listening, (void*)socketfd);//pthread_t listn, socketfd is a socket destricptor(int)     
  pthread_join(listn, NULL);

}
void* Server::listening(void *arg)
{
  int socketfd = (int)arg;
  ...
}

Normally, if I define thread function prototypes in the cpp file instead of header file, it works properly(without Server:: definition of course) Tried few other things like (void*)Server::listening, listening, (void*)listening but still didnt work. Could you enlighten me? How to pass the method parameter to listening method?

Secondly, I am learning c++ currently(already know C), is it true to use some C methods, char* arrays instead of strings, header files in the c++ program? Such as string.h, stdlib.h, pthread.h?

nihirus
  • 181
  • 1
  • 1
  • 15
  • Exact duplicate of [pthread Function from a Class](http://stackoverflow.com/questions/1151582/pthread-function-from-a-class) – Alok Save May 31 '13 at 07:21

2 Answers2

1

You can just read the error message:

type ‘void* (Server::)(void*)’ does not match ‘void* (*)(void*)‘

Because Server::listening is a non-static member function of Server, and a pointer non-static member function cannot possibly be converted to a pointer-to-non-member-function.

You have to make your Server::listening function static, or write a stand-alone function outside the Server class.

  • Please see [this question/answer](http://stackoverflow.com/a/11871465/315052) for a discussion as to why it is important to use an `extern "C"` stand-alone function. – jxh May 31 '13 at 07:31
1

You need to create a wrapper function for pthread_create(), and from there call into your class method.

class Server
{
...   
private:
int sock;
};

extern "C" void * server_listening (void *arg) {
    Server *s = static_cast<Server *>(arg);
    return s->listening();
}

void Server:: establishConnection(const char *port_number )
{
...
  this->sock = socketfd;
  pthread_create(&listn, &attrr, server_listening, this);
  pthread_join(listn, NULL);
}

The extern "C" linkage on the wrapper function is in place since pthread_create() is a C function, and expects a function pointer with C linkage. This is important if on your system the C ABI and the C++ ABI are not the same. A static method of a class can only have C++ linkage.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • got this error: Server.cpp:23:15: error: ‘void*’ is not a pointer-to-object type – nihirus May 31 '13 at 07:45
  • @nihirus: Hmpf, fat fingered the answer. Try using `s->listening()`, not `arg->listening()`. – jxh May 31 '13 at 07:49
  • firstly, thanks for your answers, still getting the same error. – nihirus May 31 '13 at 07:52
  • @nihirus: line 23, change `arg->listening()` to `s->listening()`. You can also change the cast back to `static_cast`. – jxh May 31 '13 at 07:59