473,888 Members | 1,340 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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_timerrout ine(timerroutin e); }
~A() { ::clear_timerro utine(); }
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
"referencin g 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 3062
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::cal l 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

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

Similar topics

12
2454
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 variables, but don't know how to do it ? I still receive errors when I try to use it.
2
3191
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
1128
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, it's the old 'make the user derive from a virtual base class' vs. 'use attachable callbacks (or in this case signals/slots)' problem - and I'm thinking of solving it by allowing the user to choose.
38
2070
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 syntax return old-style class, same as "class C:", and not the new style "class C(object):" ?
7
1620
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
2197
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 Message="An error occurred creating the form. See Exception.InnerException for details. The error is: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be
3
2068
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 use that parameter and pass the actual instance of the C++ class that performed the call. The C callback handler then uses the instance of the class and calls the appropriate method. Here is the code but it doesn't work. What am I doing wrong?
5
1641
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 to create a Socket object for each connection and do a BeginReceive on each socket to handle the responses. (it is clean and I can avoid the hassles of managing my own threads) My question is, will this scale well? Or is there a more efficient...
11
6275
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 the app is concerned). The problem is, If someone makes a typo, they may get an unexpected error due accidentally calling the original attribute instead of the wrapped version. Does anyone have a simple solution for this?
0
9961
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
9802
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11186
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10780
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10439
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5825
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6015
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4642
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3252
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.