James Kanze
11/28/2008 7:35:00 PM
On Nov 27, 11:49 pm, Juha Nieminen <nos...@thanks.invalid> 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::DoClick);
> 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: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