Connecting Tech Pros Worldwide Forums | Help | Site Map

Pointer to member function

Dan Smithers
Guest
 
Posts: n/a
#1: Jun 27 '08
I want to implement a C++ wrapper to C code that requires a function
pointer to be passed in. Specifically, I want a wrapper for pthread that
clients can use as a base class.

Is there a way of passing a non-static member function in that will do
this?

In the following code, if I use the static k_main then it builds and
runs, but the derived class uses the implementation in CMyThread.

If I use a virtual member function, I get a compile error:
thread2.cpp:21: error: argument of type ‘void* (CMyThread::)(void*)’
does not match ‘void* (*)(void*)’

Presumably this is because the member function pointer still expect the
this parameter when it is called.

I have thought of an alternative way that requires the CMyThread
constructor to pass the this pointer as an additional argument that is
then used in k_main to call the member function. It just looks really
horrible.


#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

class CMyThread
{
protected:
pthread_t m_thread;
void *m_args;

static void *k_main( void *ptr );
virtual void *m_main( void *ptr );
public:
CMyThread(char *name);
virtual ~CMyThread();
};

CMyThread::CMyThread(char *args)
: m_args(args)
{
int rc = pthread_create( &m_thread, NULL, m_main, (void *)args);
}

CMyThread::~CMyThread()
{
pthread_join( m_thread, NULL);
}

void *CMyThread::k_main(void *args)
{
char *message;
message = (char *) args;
printf("Base Static %s \n", message);
}

void *CMyThread::m_main(void *args)
{
char *message;
message = (char *) args;
printf("Base Virtual %s \n", message);
}

class CMyDerivedThread : public CMyThread
{
protected:
static void *k_main( void *ptr );
virtual void *m_main( void *ptr );

public:
CMyDerivedThread(char *name);
virtual ~CMyDerivedThread();
};

CMyDerivedThread::CMyDerivedThread(char *args)
: CMyThread(args)
{
}

CMyDerivedThread::~CMyDerivedThread()
{
}

void *CMyDerivedThread::k_main(void *args)
{
char *message;
message = (char *) args;
printf("Derived Static %s \n", message);
}

void *CMyDerivedThread::m_main(void *args)
{
char *message;
message = (char *) args;
printf("Derived Virtual %s \n", message);
}

main()
{
pthread_t thread1, thread2;
char *message1 = "Thread 1";
char *message2 = "Thread 2";

CMyThread t1(message1);

CMyThread t2(message2);

CMyDerivedThread("Thread 3");

exit(0);
}


tragomaskhalos
Guest
 
Posts: n/a
#2: Jun 27 '08

re: Pointer to member function


On Jun 26, 3:12*pm, Dan Smithers <dsmith...@talktalk.netwrote:
Quote:
I want to implement a C++ wrapper to C code that requires a function
pointer to be passed in. Specifically, I want a wrapper for pthread that
clients can use as a base class.
>
Is there a way of passing a non-static member function in that will do
this?
>
See http://www.parashift.com/c++-faq-lit...o-members.html



kamit
Guest
 
Posts: n/a
#3: Jun 27 '08

re: Pointer to member function


Check out boost::thread.

On Jun 26, 12:17*pm, tragomaskhalos <dave.du.verg...@logicacmg.com>
wrote:
Quote:
On Jun 26, 3:12*pm, Dan Smithers <dsmith...@talktalk.netwrote:
>
Quote:
I want to implement a C++ wrapper to C code that requires a function
pointer to be passed in. Specifically, I want a wrapper for pthread that
clients can use as a base class.
>
Quote:
Is there a way of passing a non-static member function in that will do
this?
>
Seehttp://www.parashift.com/c++-faq-lite/pointers-to-members.html
James Kanze
Guest
 
Posts: n/a
#4: Jun 27 '08

re: Pointer to member function


Dan Smithers wrote:
Quote:
James Kanze wrote:
Quote:
Quote:
Quote:
int rc = pthread_create( &m_thread, NULL, m_main, (void *)args);
Quote:
Quote:
If this compiles, your compiler is broken.
Quote:
It didn't
Quote:
Quote:
And replacing m_main
with k_main shouldn't change anything here.
Quote:
It works with g++.
That's a known bug in g++.

[...]
Quote:
Quote:
Quote:
CMyThread::~CMyThread()
{
pthread_join( m_thread, NULL);
Quote:
Quote:
pthread_join can block. I'm not sure its a good idea to
call it from a destructor. (Destructors are called during
stack walkback, in case of an exception. Which is generally
a context where you don't want to block for an indefinite
time.)
Quote:
I'll have to think of a way of tidying up if exceptions are
thrown.
It is a problem:-). And I don't know of a good solution.
(Boost detaches the thread, which is even worse than doing the
join.) What you want to do is to force the other thread to
terminate as rapidly as possible, and then join. But at least
at present, pthread_cancel doesn't work (portably) in C++, and
even if it did, it's largely advisory, at least in some of it's
aspects.
Quote:
Quote:
Quote:
}
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Closed Thread