Using function pointers in c++

M

MattWilson.6185

Hi!

I have had this problem several times before, and each time I have
been turned back forced to find another way. But not this time...

How can you cast a Class::* into a void *.

For this example I am using pthread and to start a thread you need to
pass it a void* (*)(void*)

however I have the run function inside a class:

class ThreadBase {
public:
ThreadBase() {}
virtual void run() = 0;
void start_thread() { pthread_create( &__thread_id , 0 ,this-
run , 0 ); }
void join_thread();
private:
pthread_t __thread_id;
};

Now if you inherit from this class and make a run function and call
start_thread you recieve this error:

error: cannot convert void (ThreadBase::*)() to void* (*)(void*)

This doesn't only happen with classes, if you put a function in a
namespace I believe you get a similar error.

Is there a solution, or must you solve the problem another way?

Thanks allot!

Matt
 
J

John Harrison

Hi!

I have had this problem several times before, and each time I have
been turned back forced to find another way. But not this time...

How can you cast a Class::* into a void *.

For this example I am using pthread and to start a thread you need to
pass it a void* (*)(void*)

however I have the run function inside a class:

class ThreadBase {
public:
ThreadBase() {}
virtual void run() = 0;
void start_thread() { pthread_create( &__thread_id , 0 ,this-


void join_thread();
private:
pthread_t __thread_id;
};

Now if you inherit from this class and make a run function and call
start_thread you recieve this error:

error: cannot convert void (ThreadBase::*)() to void* (*)(void*)

This doesn't only happen with classes, if you put a function in a
namespace I believe you get a similar error.

Is there a solution, or must you solve the problem another way?

Thanks allot!

Matt

Of course there is a way.

Your must pass a function of the correct type to pthread_create but
there is no reason that function cannot call ThreadBase::run

Like this

void run_my_thread(void* my_this)
{
((ThreadBase*)my_this)->run();
}

void ThreadBase::start_thread()
{
pthread_create( &__thread_id , 0 , run_my_thread , this );
}

This is a FAQ of course,

http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2

john
 
R

red floyd

Hi!

I have had this problem several times before, and each time I have
been turned back forced to find another way. But not this time...

How can you cast a Class::* into a void *.

For this example I am using pthread and to start a thread you need to
pass it a void* (*)(void*)

however I have the run function inside a class:

class ThreadBase {
public:
ThreadBase() {}
virtual void run() = 0;
void start_thread() { pthread_create( &__thread_id , 0 ,this-
void join_thread();
private:
pthread_t __thread_id;
};

Now if you inherit from this class and make a run function and call
start_thread you recieve this error:

error: cannot convert void (ThreadBase::*)() to void* (*)(void*)

This doesn't only happen with classes, if you put a function in a
namespace I believe you get a similar error.

Is there a solution, or must you solve the problem another way?

In short, you can't, nor do you want to.

http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
 
R

red floyd

John said:
Like this

void run_my_thread(void* my_this)
{
((ThreadBase*)my_this)->run();
}

Better is

extern "C" void run_my_thread(void* my_this)
{
static_cast<ThreadBase*>(my_this)->run();
}

In general, most C style callback interfaces generally require C linkage.
 
I

Ian Collins

Hi!

I have had this problem several times before, and each time I have
been turned back forced to find another way. But not this time...

How can you cast a Class::* into a void *.

For this example I am using pthread and to start a thread you need to
pass it a void* (*)(void*)

however I have the run function inside a class:

class ThreadBase {
public:
ThreadBase() {}
virtual void run() = 0;
void start_thread(){pthread_create( &__thread_id, 0, this->run, 0 );}

You just can't do this. The pthread_create function expects a C
function of the form void* (*)(void*). Any class member function will
have a hidden this parameter, which isn't a void*. A class member
function has C++ linkage.

The only correct form is to declare a function extern "C" and pass that
function to pthread_create.

extern "C" void start( void* );

void start( void *p )
{
ThreadBase *base = static_cast<ThreadBase*>(p);
base->run();
}
 
M

MattWilson.6185

extern "C" void start( void* );
void start( void *p )
{
ThreadBase *base = static_cast<ThreadBase*>(p);
base->run();

}

Thank you all very much! Worked like a charm.

Matt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top