Re: Reference to a C++ object in GTK+ callbacks



On Wednesday 14 December 2005 20:38, Wallace Owen wrote:

[snip]

Warning!

It may work for you.  It's not portable.  C++ implementations are free
to use a calling convention different from the C calling convention: In
C, parameters are pushed in reverse order to support varargs.  C++
functions are specified in the standard as not supporting varargs so
that compiler vendors are free to use certain optimizations.  For
example, in C, it's the caller's responsibility to clean up the stack
after a call because the called function can't know at compile time how
many parms were passed.  C++ compilers are free to optimize this such
that the called function does the stack cleanup, so that a function
that's called from many different places only has one stack cleanup
chunk generated.

It's for this reason that a static function should be used to catch
callbacks, so it can cast the parameter to a pointer to the object, then
invoke the member function.  Static member functions don't have an
implied first parm that's it's object.  See below:

class Foo
{
public:
      static redrawCB(Event *event, void *parm)
      {
              Foo *obj = reinterpret_cast<Foo*>(parm);
              obj->redraw(event);
      }

      redraw(Event *event)
      {
        ...
      }
};

Your version isn't portable either.  GTK+ callbacks required C linkage, so to 
be portable your code should provide C linkage, and static member functions 
cannot have C linkage.  This means that to be portable the callback has to be 
declared extern "C" in file scope (and if it needs access to the class's 
internals, needs to be declared a friend in the class definition).

Paragraph 7.5.1 of the standard says this:

"All function types, function names, and variable names have a language
linkage. The default language linkage of all function types, function names,
and variable names is C++ language linkage. Two function types with
different language linkages are distinct types even if they are otherwise
identical."

Static member functions happen to work with g++.  They may not work with other 
compilers.

Chris




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]