Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!tut.cis.ohio-state.edu!ucbvax!bloom-beacon!dont-send-mail-to-path-lines From: bob@odi.COM (Bob Miner) Newsgroups: comp.windows.x Subject: Re: C++ and X: Member-Functions as Callbacks Message-ID: <9103091835.AA05512@odi.com> Date: 9 Mar 91 18:35:57 GMT References: <1991Mar9.123358.14352@csn.org> Sender: daemon@athena.mit.edu (Mr Background) Organization: The Internet Lines: 79 Howdy. Help requested from C++ and X gurus: I am trying to set up a callback for an X widget. I would LIKE to have the callback be a member-function of a C++ class. An example: struct blah { void foo(); } .... blah instance; XtAddCallback( ---- , ---- , instance.foo, ---- ); The problem(s): When I try it (as in the example), foo() is not called with the proper, hidden, THIS* argument. THIS, in fact, points to a mess. I suspected that X is packing the normal callback arguments where they shouldn't be (w, client_data, and call_data), so I tried explicitly specifying the arguments: struct blah { void foo(Widget, caddr_t, caddr_t); } But it still doesn't work. THIS still points somewhere else. Any ideas? I'm sorry if this isn't more clear. I'm rather new to both X and C++. Jeff Rink (rink@tramp.colorado.EDU) To the best of my knowledge, there's no way to make Xt directly call a C++ member function. If there is, I'd love to hear it. The way to make Xt and C++ work together is to create a static C++ function as the callback function for each callback. This function receives events, determines which C++ object should handle the event and then passes the event to that C++ object. Your callback function can determine which C++ object to call in at least two ways. One way is to, when you add the callback to the widget, set the clientData (the second arg) to be a pointer to your C++ object. Then, when you get the callback, cast the clientData to a pointer to the appropriate C++ type and call the appropriate event handling function on the C++ object. Another way which can be used for some toolkits (OSF/Motif at least) is to, when creating the widget, set the userData resource on the widget to be a pointer to the corresponding C++ object. Then, when you get the callback, get the userData resource from the given widget and cast the userData resource value to the appropriate C++ type and call the appropriate event handling function on that C++ object. I've also heard of people using hash tables to map widgets to C++ objects, but I'm not sure what advantage that has over the above two alternatives. Bob Miner ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Object Design, Inc. ~ OOOOOO 1 New England Executive Park ~ OOOO OOOO Burlington, MA 01803-5005 USA ~ OOOOO OOOOO bob@odi.com -or- uunet!odi!bob ~ OOOO OOOO voice: (617) 270-9797 FAX: (617) 270-3509 ~ OOOOOO bject Design Inc. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "From there to here, from here to there, funny things are everywhere." - Dr. Seuss ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~