Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Problems with callback

Reply
Thread Tools

Problems with callback

 
 
maverik
Guest
Posts: n/a
 
      11-26-2008
Hi.

I have class ListView

ListView.h:

class ListView {
...
typedef void (*ListViewCallback)(ListViewItem& );
...
void SetMouseButtonUpCb(ListViewCallback );
...
};

and some other class MyClass:

MyClass.h:

#include "ListView.h"
class MyClass {
...
ListView m_listView;
...
};

MyClass.cpp:

#include "ListView.h"

void
MyClass::Foo() {
m_listView.SetMouseButtonUpCb(&GDoClick); // That's ok
m_listView.SetMouseButtonUpCb(&MyClass:oClick); // Error

// 'ListView::SetMouseButtonUpCb' : cannot convert parameter 1 from
'void (__thiscall MyClass::*) (ListViewItem &)' to
'ListView::ListViewCallback'

}

void
MyClass:oClick(ListViewItem& item) {
...
}

void
GDoClick(ListViewItem& item) {
...
}

Where DoClick(ListViewItem& ) is member of MyClass and GDoClick
(ListViewItem& ) is a global function.
As you can see registring global function GDoClick as a callback is
OK, but registring a member of the class produce an error.
Unfortunately, I have some restrictions:

1. I cannot change callback definition. For example, I can't write

typedef void (*MyCLass::ListViewCallback)(ListViewItem& );

2. I cannot use global function as a callback. Can't do this:

m_listView.SetMouseButtonUpCb(&GDoClick);

Question: is there a way in that i can do this (can register class
method as a callback):

m_listView.SetMouseButtonUpCb(&MyClass:oClick);

Thanks.
 
Reply With Quote
 
 
 
 
Puppet_Sock
Guest
Posts: n/a
 
      11-26-2008
On Nov 26, 1:36*pm, maverik <(E-Mail Removed)> wrote:
[snip]
> Question: is there a way in that i can do this (can register class
> method as a callback):
>
> * * m_listView.SetMouseButtonUpCb(&MyClass:oClick);


This is an evergreen question in C++.

Think carefully what you are doing. A non-static
member function has not got an object to work in
until that object is created. And it can't find
that object unless you tell it how some way,
such as by using the object's name, or by calling
it through the object's address.

So your example

m_listView.SetMouseButtonUpCb(&MyClass:oClick);

can't work without some modifications. Which
specific instance of MyClass do you want to
do the DoClick op?

If you are restricted in being unable to change the
signature of the callback then you have to use some
kind of "look up" strategy.

Someplace, you have to store the address of the
specific object you want. Then, you make a static
callback function that uses that address to forward
the request to the specific object, and returning
the appropriate data where it belongs.

In some callback systems you can pass the address
in as a parameter. In other cases you need some
way to save the object's address in your code,
and some way to pick the specific object you want.

If I recall, Microsoft windows lets you pass an
extra parameter to such callbacks. This might
not be acceptable as an address, but might be
ok as something that lets you look up an object
instance in a table, and get the address. The
system uses window handles or something.
Window handle or something, if I recall.
Socks
 
Reply With Quote
 
 
 
 
Andrey Tarasevich
Guest
Posts: n/a
 
      11-26-2008
maverik wrote:
>
> Question: is there a way in that i can do this (can register class
> method as a callback):
>
> m_listView.SetMouseButtonUpCb(&MyClass:oClick);
>


http://www.parashift.com/c++-faq-lit....html#faq-33.2

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      11-27-2008
maverik wrote:
> Question: is there a way in that i can do this (can register class
> method as a callback):
>
> m_listView.SetMouseButtonUpCb(&MyClass:oClick);


A member function can not be called using a function pointer only for
the simple reason that a member function *always* needs an object as
well. (Basically you can think that a pointer to the object is always
passed to the member function as the first parameter. Which is usually
actually the case internally with most compilers.)

If the callback mechanism only supports taking a function pointer and
nothing else, then it obviously cannot call a member function because it
has no object pointer to give.

Most callback function mechanisms support taking some user data,
usually in the form of a void*. What you do is that you give a pointer
to the object as this void*, and then use a regular callback function
which receives that void*. That callback function then just
reinterpret-casts the void* to the type of the class and uses it to call
the member function.

If you are writing the callback mechanism yourself, then you can
automatize this to great lengths using templates, but it's a bit
complicated.
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      11-28-2008
On Nov 27, 11:49*pm, Juha Nieminen <(E-Mail Removed)> wrote:
> maverik wrote:
> > Question: is there a way in that i can do this (can register
> > class method as a callback):


> > * * m_listView.SetMouseButtonUpCb(&MyClass:oClick);


> A member function can not be called using a function pointer
> only for the simple reason that a member function *always*
> needs an object as well. (Basically you can think that a
> pointer to the object is always passed to the member function
> as the first parameter. Which is usually actually the case
> internally with most compilers.)


> If the callback mechanism only supports taking a function
> pointer and nothing else, then it obviously cannot call a
> member function because it has no object pointer to give.


Back in the good old days, people used static variables (and
"good" is meant very, very ironically).

> Most callback function mechanisms support taking some user
> data, usually in the form of a void*. What you do is that you
> give a pointer to the object as this void*, and then use a
> regular callback function which receives that void*. That
> callback function then just reinterpret-casts the void* to the
> type of the class and uses it to call the member function.


First, it's static_cast you want, not reinterpret_cast. And
second, you have to be very, very careful; the static_cast must
be to exactly the type which served to get the void*. So, for
example, something like:

extern "C" void callback( void* p )
{
static_cast< Base* >( p )->doSomething() ;
}

// ...

Derived theObject ;
registerCallback( &callback, &theObject ) ;

is undefined behavior (supposing registerCallback takes a void*
as second argument). You must do:

registerCallback( &callback,
static_cast< Base* >( &theObject ) ) ;

> If you are writing the callback mechanism yourself, then you
> can automatize this to great lengths using templates, but it's
> a bit complicated.


Particularly if the interface requires an ``extern "C"''
function (which is usually the case).

--
James Kanze (GABI Software) email:(E-Mail Removed)
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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
it won't callback,pls help fisher Cisco 0 07-26-2004 01:20 AM
Callback and DDR Profiles problems or is it to do with isdn? Phil Cisco 0 02-26-2004 09:49 AM
isdn callback Andree Toonk Cisco 0 11-12-2003 04:09 PM
Radius / IAS and ISDN Callback jt Cisco 0 10-17-2003 11:39 AM
Cache with Callback problems... threading? Brian Vallelunga ASP .Net 3 07-27-2003 03:37 AM



Advertisments