473,326 Members | 2,175 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

registering class methods as C style callbacks

consider the following problem:

You have a C style library and API that uses callbacks to implement
functionality. Examples of this are X11 API, OpenGL/GLUT...The List goes
on.

The power of virtuals in C++ leads us to want to implement a framework
where those callbacks are simply overriden virtual methods in a derived
class. So...

struct A {
A() { ::set_timerroutine(timerroutine); }
~A() { ::clear_timerroutine(); }
void timerroutine() { action(); }
virtual void action()=0;
};

struct B: public A {
B(): A() {}
action() { // do something relevant here }
};

B myTimerObject;
On the surface we would expect that registering the class method
timerroutine in the constructor for A would cause B::action() to be
invoked but I've not found a way to cast a class method to a generic
function pointer as is expected in C style callbacks.

How can I accomplish this without the extremely ugly overhead of
"referencing static object pointers in a C style timerroutine() that is
not itself a class method?"

The idea/requirement is to have a framework that can exist solely in a
header file and thus serve as a template.

-Rob
Jul 17 '06 #1
13 3018
no***@all.com wrote:
On the surface we would expect that registering the class method
timerroutine in the constructor for A would cause B::action() to be
invoked but I've not found a way to cast a class method to a generic
function pointer as is expected in C style callbacks.
A cast is not enough. To use a member function you need both the function
and an object.

Systems with callbacks usually provide a way to pass a pointer to the
function that sets the callback, and pass this pointer value when calling
the callback function. You just need to use a pointer to a base class, and
use it to call the virtual function you want.

--
Salu2
Jul 17 '06 #2
On Mon, 17 Jul 2006 21:22:00 +0200, Julián Albo wrote:
no***@all.com wrote:
>On the surface we would expect that registering the class method
timerroutine in the constructor for A would cause B::action() to be
invoked but I've not found a way to cast a class method to a generic
function pointer as is expected in C style callbacks.

A cast is not enough. To use a member function you need both the function
and an object.

Systems with callbacks usually provide a way to pass a pointer to the
function that sets the callback, and pass this pointer value when calling
the callback function. You just need to use a pointer to a base class, and
use it to call the virtual function you want.
Either I'm not understanding your explanation or you don't understand my
problem fully: maybe a bit of both. registering a callback simply uses a
function pointer (ptr*)() and since class methods are not really function
pointers they cannot be directly registered in APIs that use C style
callbacks. I need a way of registering them that does NOT require static
pointers, or global C functions to get around the function pointer
problem. this solution MUST be fully implementable in a header file so
that it can serve as a template.
Jul 17 '06 #3
no***@all.com wrote:
Either I'm not understanding your explanation or you don't understand my
problem fully: maybe a bit of both. registering a callback simply uses a
function pointer (ptr*)() and since class methods are not really function
pointers they cannot be directly registered in APIs that use C style
callbacks. I need a way of registering them that does NOT require static
pointers, or global C functions to get around the function pointer
problem. this solution MUST be fully implementable in a header file so
that it can serve as a template.
The fact that you want it does not make it possible. If you want to use a
non static member function you need a way to provide an object. If the
callback style does not allow it, you need to use a global variable or some
other workaround.

--
Salu2
Jul 17 '06 #4
// This should see you on your way.

#include <cstddef>
#include <ostream>
using namespace std;

struct demo
{
void
func()
{
cout << "called" << endl;
}
};

template< typename xObj, void (xObj::*xPtr)() >
struct
bound_func
{
static
xObj
obj;

static
void
call()
{
(obj.*xPtr)();
}
};

template< typename xObj, void (xObj::*xPtr)() >
xObj
bound_func< xObj, xPtr >::obj;

int
main()
{
typedef bound_func< demo, &demo::func tBound;
tBound::call();
// &tBound::call should be suitable for a callback
}
Jul 17 '06 #5

Julián Albo wrote:
no***@all.com wrote:
Either I'm not understanding your explanation or you don't understand my
problem fully: maybe a bit of both. registering a callback simply uses a
function pointer (ptr*)() and since class methods are not really function
pointers they cannot be directly registered in APIs that use C style
callbacks. I need a way of registering them that does NOT require static
pointers, or global C functions to get around the function pointer
problem. this solution MUST be fully implementable in a header file so
that it can serve as a template.

The fact that you want it does not make it possible. If you want to use a
non static member function you need a way to provide an object. If the
callback style does not allow it, you need to use a global variable or some
other workaround.

--
Salu2
My C++ is a little rusty (and I don't have a compiler handy to try) -
so ignore me if I'm talking dribble. Is it possible that mem_fun_ref
can be used to create a unary function object, which is then passed to
the callback? But like I say, not sure that would work, or indeed, if
it's safe. However, could throw a possible angle on things (or not...)
Jon.

Jul 17 '06 #6
Jon Clements wrote:
[..]
My C++ is a little rusty (and I don't have a compiler handy to try) -
so ignore me if I'm talking dribble. Is it possible that mem_fun_ref
can be used to create a unary function object, which is then passed to
the callback? But like I say, not sure that would work, or indeed, if
it's safe. However, could throw a possible angle on things (or not...)
Any templates from C++ Standard Library (and objects derived therefrom)
are useless when C callbacks are concerned). C has no idea about any
"function objects".

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 17 '06 #7
Jon Clements wrote:
My C++ is a little rusty (and I don't have a compiler handy to try) -
so ignore me if I'm talking dribble. Is it possible that mem_fun_ref
can be used to create a unary function object, which is then passed to
the callback? But like I say, not sure that would work, or indeed, if
it's safe. However, could throw a possible angle on things (or not...)
mem_fun_ref has no magic, it just creates objects that pass references to
the object you pass and the member function you want to use. The problem is
the same as if you write a specific class for the task.

What specific problem are you trying to solve? Maybe there are other ways to
do the task.

--
Salu2
Jul 17 '06 #8

Victor Bazarov wrote:
Any templates from C++ Standard Library (and objects derived therefrom)
are useless when C callbacks are concerned). C has no idea about any
"function objects".
Surely though - if it just dereferences the function object (or pointer
to it maybe?), it doesn't even need to know it's a function object?

Jon.

Jul 17 '06 #9

Julián Albo wrote:
mem_fun_ref has no magic, it just creates objects that pass references to
the object you pass and the member function you want to use. The problem is
the same as if you write a specific class for the task.

What specific problem are you trying to solve? Maybe there are other waysto
do the task.
Was just wondering if it was a possible solution for the OP. However, I
think Victor and yourself have enlightened me to the fact, this
wouldn't be a solution.

Just seemed to make sense at the time of generating a function object
and passing the address of that to the callback....

Cheers

Jon

Jul 17 '06 #10
Jon Clements wrote:
Victor Bazarov wrote:
>Any templates from C++ Standard Library (and objects derived therefrom)
are useless when C callbacks are concerned). C has no idea about any
"function objects".

Surely though - if it just dereferences the function object (or pointer
to it maybe?), it doesn't even need to know it's a function object?

Jon.
It also passes a pointer to the object to the function (its the "this"
pointer). That's the problem.

a.func() is kindof the same as func(&a), not func().
Jul 17 '06 #11
Jon Clements wrote:
>mem_fun_ref has no magic, it just creates objects that pass references to
the object you pass and the member function you want to use. The problem
is the same as if you write a specific class for the task.

What specific problem are you trying to solve? Maybe there are other ways
to do the task.

Was just wondering if it was a possible solution for the OP. However, I
Sorry, 'you' intended to be 'the OP'

--
Salu2
Jul 17 '06 #12
On Mon, 17 Jul 2006 20:02:47 +0000, Howard Gardner wrote:
template< typename xObj, void (xObj::*xPtr)() >
struct
bound_func
{
static
xObj
obj;

static
void
call()
{
(obj.*xPtr)();
}
};

thanks, but wouldn't

static xObj obj

also need to be defined in a source file as well as being declared in the
template header as you show above? the requirement of a definition in a
related source file is what I'm trying to get away from.
Jul 22 '06 #13
noone wrote:
On Mon, 17 Jul 2006 20:02:47 +0000, Howard Gardner wrote:
>template< typename xObj, void (xObj::*xPtr)() >
struct
bound_func
{
static
xObj
obj;

static
void
call()
{
(obj.*xPtr)();
}
};


thanks, but wouldn't

static xObj obj

also need to be defined in a source file as well as being declared in
the template header as you show above? the requirement of a
definition in a related source file is what I'm trying to get away
from.
Since it's a member of a class template, it's a template itself. You
don't need to define it in a source file, but you need to define it
outside the class template, in the same header. When you use it, the
static data member will be first *instantiated* and then *initialised*
according to your "definition" statement. You needn't worry about
putting it in a source file somewhere.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 24 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: MacFly | last post by:
Hi everyone, HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD dwMessageId, PVOID pMsgBuffer) I want that method to be class member method so it could have access to class...
2
by: Bill Nguyen | last post by:
How can I create a shared function to display process progress that can be called from other routines within an application? Any example that I can follow? Thanks Bill
0
by: Asfand Yar Qazi | last post by:
Hi, Is is possible to set the 'policy' of a class by allowing the user to specify a template argument that defines what some functions will be based on the template argument given? Basically,...
38
by: looping | last post by:
For Python developers around. >From Python 2.5 doc: The list of base classes in a class definition can now be empty. As an example, this is now legal: class C(): pass nice but why this...
7
by: Chris Jewell | last post by:
Hi, I'm wondering what the best way of registering a data storage class with a data handler class is. At the moment I have two classes: class EpiCovars // Storage class { ....
1
by: shivkumar2004 | last post by:
Hi!, I am developing a chat system using vb.net in vs 2005. I am getting the following error while registering the events. error details: System.InvalidOperationException was unhandled...
3
by: SpreadTooThin | last post by:
I have a C routine that wants to call a method of its user. In this case the method is a method inside a class. The C routine is passed a void * which can be used by the user any way they like. I...
5
by: Bruce | last post by:
Hello I am building a C# app that creates anywhere from 10 to 100 connections to a specified server and sends 1000s of TCP requests and processes the responses. (it is a stress tool) I planned...
11
by: Rafe | last post by:
Hi, I'm working within an application (making a lot of wrappers), but the application is not case sensitive. For example, Typing obj.name, obj.Name, or even object.naMe is all fine (as far as...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shćllîpôpď 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.