francis@sunquest.UUCP (Francis Sullivan) (10/20/89)
I would like to be able to use C++ callbacks in X11. Since this is not supported, I'm trying to come up with a simple method to simulate this. For now I just write a C wrapper that calls the correct C++ routine, but I get the feeling that there is an easier way. here is an example using wrappers: class dud { char name[8]; public: dud(char *n) { strcpy(name, n);}; who() {printf ("I am %s\n", name);}; }; dud big("big"); dud dum("dum"); // dummy wrappers wrap_big_who() { big.who(); } wrap_dum_who() { dum.who(); } some_prog() { // what I would like // XCallMeBack(big.who); // XCallMeToo(dum.who); // what I have to use XCallMeBack(wrap_big_who); XCallMeToo(wrap_dum_who); } --- Anyway, a cpp method or a c++ method for dealing with the above is desirable. Suggestions are welcome,
haynes@gnome5.pa.dec.com (Charles Haynes) (10/20/89)
Use the "this" pointer as the client data in the X callback. Write a generic wrapper function that takes a class pointer, and a pointer to a method, and calls that method in that class. The method should have no other args. Use the wrapper as the callback and the class as the client data. -- Charles
dog@cbnewsl.ATT.COM (edward.n.schiebel) (10/20/89)
From article <640@sunquest.UUCP>, by francis@sunquest.UUCP (Francis Sullivan): > I would like to be able to use C++ callbacks in X11. Since this is not > supported, I'm trying to come up with a simple method to simulate this. > For now I just write a C wrapper that calls the correct C++ routine, but > I get the feeling that there is an easier way. [...code deleted...] I have implemented one solution in SunView, but it seems to be the same problem. First, I have an abstract base class class dispatchable { public: virtual int doit() = 0; }; the application derives specific classes from this one to do the program's stuff. Now, each Button, Menu_item etc. is given a dispatchable* (either through some client data mechanism or by creating a class Button which encapsulates the X/SunView implementation). When a button is pressed, grab its dispatchable* and call doit(). As an aside, I have noticed to get anything like this to work well takes a lot more time up front providing support classes etc., but in the end, the application is so much easier to write. Hope this is useful, it has worked for me. Ed Schiebel AT&T Bell Laboratories dog@vila.att.com 201-386-3416
keffer@blake.acs.washington.edu (Thomas Keffer) (10/21/89)
In article <1948@bacchus.dec.com> haynes@gnome5.pa.dec.com (Charles Haynes) writes: >Use the "this" pointer as the client data in the X callback. Write a >generic wrapper function that takes a class pointer, and a pointer to a >method, and calls that method in that class. The method should have no >other args. Use the wrapper as the callback and the class as the client data. > This is essentially the strategy that I have followed with SunView except that I make the callback routine a static member function of the appropriate class (in my case, I have defined a ``Panel'' class that manages a window). The callback routine looks something like: void Panel::someButtonCallBack(Panel_item p, int value, Event *e) { PanelClient* this_client = panel_get(p, CLIENT_DATA); this_client->memberFunctionYouWantToCall(value); } Or something like that. Here, PanelClient is the object being maniupulated on behalf of the window. The advantage of using a static member function is to further encapsulation while giving you access to the appropriate member functions and variables. An example is available via anonymous ftp from sperm.ocean.washington.edu in file ~ftp/pub/spinup.tar.Z -Tom Keffer Rogue Wave P.O. Box 85341 Seattle Wa 98145-1341 (206) 523-5831