Deal with C style function pointer callback in an object

D

Dat Chu

I want to write an class that hide away the function pointer
callbacks. That is:

Normally i create this function:
void errorCallback(char * err_msg)

then I call
registerErrorCallback(&errorCallback)

Then when there is an error in this third party module, my
errorCallback function will get called.

However, I would like to make this as a clean OO implementation. I
face with a problem, how can I pass a function to
registerErrorCallback that when call will make some change the state
of my object?

I got stuck with some singleton-like implementation but I am not sure
if this is a good idea.

Dat Chu
 
I

Ian Collins

Dat said:
I want to write an class that hide away the function pointer
callbacks. That is:

Normally i create this function:
void errorCallback(char * err_msg)

then I call
registerErrorCallback(&errorCallback)

Then when there is an error in this third party module, my
errorCallback function will get called.

However, I would like to make this as a clean OO implementation. I
face with a problem, how can I pass a function to
registerErrorCallback that when call will make some change the state
of my object?

There isn't really a lot you can do.

You can pass a friend function which updates a singleton class (or
static data), but that's as far as you can go with that API.
 
J

James Kanze

I want to write an class that hide away the function pointer
callbacks. That is:
Normally i create this function:
void errorCallback(char * err_msg)
then I call
registerErrorCallback(&errorCallback)
Then when there is an error in this third party module, my
errorCallback function will get called.
However, I would like to make this as a clean OO
implementation. I face with a problem, how can I pass a
function to registerErrorCallback that when call will make
some change the state of my object?

If you're defining it, you can either use a pointer to an
abstract base class, requiring the client to derive his callback
from this base class, or you can use something like
boost::function (which IIRC will be in the next version of the
standard).

If you're dealing with an existing C interface, you're stuck.
(But most such interfaces provide an additional void* for user
data---you can use this to pass a pointer to your abstract base
class or functional object.)
`
 
F

Frank Neuhaus

----- Original Message -----
From: "Dat Chu" <[email protected]>
Newsgroups: comp.lang.c++
Sent: Saturday, May 16, 2009 7:12 AM
Subject: Deal with C style function pointer callback in an object

I want to write an class that hide away the function pointer
callbacks. That is:

Normally i create this function:
void errorCallback(char * err_msg)

then I call
registerErrorCallback(&errorCallback)

Then when there is an error in this third party module, my
errorCallback function will get called.

However, I would like to make this as a clean OO implementation. I
face with a problem, how can I pass a function to
registerErrorCallback that when call will make some change the state
of my object?

You can use boost::functions[1]
define your registerErrorCallback like this:
void registerErrorCallback(boost::function<void ( const char* )> fn);

Then say you are in your class XY:
class XY
{
[...]
void init()
{
registerErrorCallback(boost::bind(&XY::myErrorCallback,boost::ref(*this),_1));
}
void myErrorCallback(const char* err)
{
std::cout << err << std::endl;
}
}

The boost::bind call will bind the 'this' pointer to the member function
pointer making it a normal boost::function<void ( const char* )> that does
not use your class instance anymore.

Hope this helps
Frank

[1] http://www.boost.org/doc/libs/1_39_0/doc/html/function.html
 
I

Ian Collins

Frank said:
----- Original Message ----- From: "Dat Chu" <[email protected]>
Newsgroups: comp.lang.c++
Sent: Saturday, May 16, 2009 7:12 AM
Subject: Deal with C style function pointer callback in an object

I want to write an class that hide away the function pointer
callbacks. That is:

Normally i create this function:
void errorCallback(char * err_msg)

then I call
registerErrorCallback(&errorCallback)

Then when there is an error in this third party module, my
errorCallback function will get called.

However, I would like to make this as a clean OO implementation. I
face with a problem, how can I pass a function to
registerErrorCallback that when call will make some change the state
of my object?

You can use boost::functions[1]
define your registerErrorCallback like this:
void registerErrorCallback(boost::function<void ( const char* )> fn);

Not a lot of use if registerErrorCallback is part of an existing C API.
 
F

Frank Neuhaus

Ian Collins said:
Frank said:
----- Original Message ----- From: "Dat Chu" <[email protected]>
Newsgroups: comp.lang.c++
Sent: Saturday, May 16, 2009 7:12 AM
Subject: Deal with C style function pointer callback in an object

I want to write an class that hide away the function pointer
callbacks. That is:

Normally i create this function:
void errorCallback(char * err_msg)

then I call
registerErrorCallback(&errorCallback)

Then when there is an error in this third party module, my
errorCallback function will get called.

However, I would like to make this as a clean OO implementation. I
face with a problem, how can I pass a function to
registerErrorCallback that when call will make some change the state
of my object?

You can use boost::functions[1]
define your registerErrorCallback like this:
void registerErrorCallback(boost::function<void ( const char* )> fn);

Not a lot of use if registerErrorCallback is part of an existing C API.

Hm right sorry - I missed the part that registerErrorCallback is in a third
party lib ;).
 
Joined
Aug 24, 2009
Messages
3
Reaction score
0
Hi all,

I have developed a library using pthread that other developers are using in their applications. Now I am trying to replace pthread calls with boost API. I have a similar question about C-style function pointers in boost.

One of the classes in my library (CThread) is as follows:

class CThread
{
public:
...
template<class TContext>
void Start(TContext& context, void (TContext::*pFunc)(void*))
{
#if USE_BOOST
_thread = new ::boost::thread:):boost::bind:):Run, new CCallback<TContext, void*>(context, pFunc))); // note: _thread is of type boost::thread*
#else
int nResult = 0;

nResult = pthread_attr_init(&_attr);
assert(nResult == 0);

nResult = pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_JOINABLE);
assert(nResult == 0);

nResult = pthread_create(&_thread, &_attr, ::Run, new CCallback<TContext, void*>(context, pFunc));
assert(nResult == 0);
#endif
}
};


CThread::Start will start a thread where the provided TContext and pFunc are used to call back to the application. For instance,

class C
{
public:
...

void MyRun(void*)
{
while (_bExit == false)
{
...
}
}

private:
bool _bExit;
};

void main(int argc, char* argv[])
{
C c;
CThread t;

t.Start(c, &C::MyRun);
...
}


The above works fine when using either pthread or boost; some C-function Run is invoked where the argument (some callback) is used to do the actual callback to pFunc using the correct context and passing NULL as parameter.

Now my question. Since boost is OO, is it possible to do the call directly to the TContext::*pFunc instead of using some de-tour via ::Run. I looked into boost::function but somehow that didn't help me.

Any help is very much appreciated, regards,
Mark
 
Joined
Aug 24, 2009
Messages
3
Reaction score
0
MarkyMark101 said:
Hi all,

I have developed a library using pthread that other developers are using in their applications. Now I am trying to replace pthread calls with boost API. I have a similar question about C-style function pointers in boost.

One of the classes in my library (CThread) is as follows:

class CThread
{
public:
...
template<class TContext>
void Start(TContext& context, void (TContext::*pFunc)(void*))
{
#if USE_BOOST
_thread = new ::boost::thread:):boost::bind:):Run, new CCallback<TContext, void*>(context, pFunc))); // note: _thread is of type boost::thread*
#else
int nResult = 0;

nResult = pthread_attr_init(&_attr);
assert(nResult == 0);

nResult = pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_JOINABLE);
assert(nResult == 0);

nResult = pthread_create(&_thread, &_attr, ::Run, new CCallback<TContext, void*>(context, pFunc));
assert(nResult == 0);
#endif
}
};


CThread::Start will start a thread where the provided TContext and pFunc are used to call back to the application. For instance,

class C
{
public:
...

void MyRun(void*)
{
while (_bExit == false)
{
...
}
}

private:
bool _bExit;
};

void main(int argc, char* argv[])
{
C c;
CThread t;

t.Start(c, &C::MyRun);
...
}


The above works fine when using either pthread or boost; some C-function Run is invoked where the argument (some callback) is used to do the actual callback to pFunc using the correct context and passing NULL as parameter.

Now my question. Since boost is OO, is it possible to do the call directly to the TContext::*pFunc instead of using some de-tour via ::Run. I looked into boost::function but somehow that didn't help me.

Any help is very much appreciated, regards,
Mark

anyone?

How do I callback to a C++ method within a given context?

Mark
 

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
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top