home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / windows / openloo / 3631 < prev    next >
Encoding:
Internet Message Format  |  1992-08-27  |  5.5 KB

  1. Path: sparky!uunet!cs.utexas.edu!ut-emx!ccwf.cc.utexas.edu!filo
  2. From: filo@ccwf.cc.utexas.edu (John Filo)
  3. Newsgroups: comp.windows.open-look
  4. Subject: Re: Q: C++ and callback problems.
  5. Message-ID: <FILO.92Aug27190611@doc.cc.utexas.edu>
  6. Date: 28 Aug 92 00:06:11 GMT
  7. References: <1737@ernohb.UUCP> <1992Aug24.171121.27530@isy.liu.se>
  8. Sender: news@ut-emx.uucp
  9. Organization: The University of Texas at Austin
  10. Lines: 120
  11. In-reply-to: svan@isy.liu.se's message of 24 Aug 92 17:11:21 GMT
  12.  
  13. In article <1992Aug24.171121.27530@isy.liu.se> svan@isy.liu.se (Jonas Svanberg) writes:
  14.  
  15. > I'm using xview myself and have given up the idea of having a nice
  16. > and pure objectoriented system without old-c-style functions :-)
  17.  
  18. I've been able to use c++ with xview with some success, although the 
  19. way I went about it is sort of a kludge, and after reading Steve's
  20. article I realized that this method will only work on member functions 
  21. that aren't virtual, so that might limit it's usefulness.
  22.  
  23. Below is a copy of a message I sent someone a few months back
  24. addressing this same issue.  Since I missed the original poster's
  25. question, I don't know if this will help you since the details are
  26. specific to xview, but I imagine a similar scheme could be worked out
  27. with most other toolkits.
  28.  
  29. =========================================================================
  30. I've used C++ with xview before on a Sun.  I only had two problems.
  31. First, C++ requires prototypes for all functions.  If your header
  32. files don't handle this correctly, then you'll have to write prototypes
  33. yourself, which can be a real pain in the ass.  The include files that 
  34. come with Sun's xview handles this correctly so it wasn't really much of
  35. a problem for me, except for tha fact that one of the include files had
  36. to be modified in order for it to compile correctly.
  37.  
  38. The second problem is more serious and has to do with using member 
  39. functions as callback procedures.  For example lets say you have an object 
  40. that contains a Canvas and you want to use one of the member functions for 
  41. it's repaint procedure. When xview invokes the repaint procedure, it will 
  42. pass the arguments (Canvas, Xv_window, Display...) as if it were a regular 
  43. C function. However, C++ expects an undeclared, implied "this" pointer to
  44. passed as the first parameter.  This has the effect of shifting all the 
  45. parameters one place to the left, with the Canvas id equal to the 
  46. Xv_window id, the Xv_window id equal to the Display pointer and so on.  
  47. The "this" pointer ends up being set to Canvas id.
  48. There are several solutions to this problem.
  49.  
  50.   1. Don't use member functions for callbacks.  
  51.      This isn't a very good solution since it reduces the usefullness
  52.      of C++.
  53.   2. Use a static member function that calls a non-static member 
  54.      function.  This way, all the callback stuff is encapsulated
  55.      inside the class containing the callback.  However, in order
  56.      for this to work, the static member function must know
  57.      which object to use when invoking the non-static member
  58.      function. This can be accomplished with the following:
  59.  
  60.     // comewhere in cObject initialization
  61.         xv_set(xvObject, 
  62.                XV_KEY_DATA, KEY_THIS_PTR, &cObject,
  63.                ???_PROC, staticCallback, 
  64.                NULL);
  65.  
  66.      then, inside the static callback, you can get the object pointer
  67.      as follows:
  68.  
  69.         staticCallback(XVObject xvObject, /* other args */)
  70.         {
  71.           CObject  *cObject;
  72.  
  73.           cObject = (CObject*) xv_get(xvObject, XV_KEY_DATA, KEY_THIS_PTR);
  74.           cObject->nonStaticCallback(xvObject, /* other args */);  
  75.         }
  76.  
  77.      This is kind of messy, but at least all the mess is hidden in the class
  78.      definition.  My only complaint about this method is that you have to 
  79.      define a static and non-static function for every callback.
  80.  
  81.   3. Use a technique similar to the one above, but without the static member
  82.      function.
  83.  
  84.  
  85.     // somewhere in cObject initialization 
  86.           xv_set(xvObject,
  87.                  XV_KEY_DATA, KEY_THIS_PTR, &cObject,
  88.                  ???_PROC, nonstaticCallback,  //a weird case is required 
  89.                  NULL);                        //here, but I'll have to 
  90.                                                //look it up.
  91.  
  92.      then, inside the nonstatic callback,
  93.  
  94.          // note the lack of the XVobject arg, it's stored in the "this" ptr;
  95.          nonstaticCallback(/* other args */
  96.          {
  97.              XVObject  xvObject = (XVObject *) this;
  98.              this = xv_get(xvObject, XV_KEY_DATA, KEY_THIS_PTR);
  99.              ...
  100.              // procede as you would in any c++ member function
  101.          }
  102.  
  103.      I prefer this method, since all the work is in one place.
  104.      However, the assignment to the "this" pointer is probably 
  105.      considered a no-no, and may even be obsolete.  I used 
  106.      AT&T's CC, version 2.0, and I think the mention something 
  107.      about it being kept in there for backwards compatability,
  108.      but at some point would be removed from the language,
  109.      so this may be unwise.  An alternative is to the following
  110.      in the callback
  111.  
  112.          nonstaticCallback(/* other args */)
  113.          {
  114.              XVObject  xvObject = (XVObject *) this;
  115.              CObject *me = xv_get(xvObject, XV_KEY_DATA, KEY_THIS_PTR);
  116.              ...
  117.              // now all members must be prepended with me->.  this is
  118.              // very ugly and error prone, and probably not a good idea.
  119.           }
  120.  
  121.       If you want ensured compatability in the future, I would probably 
  122.       recommend method 2, although I use the 3rd method.  
  123.  
  124. Hope this helps,
  125.  
  126. John Filo
  127. filo@ccwf.cc.utexas.edu
  128.  
  129.  
  130.  
  131.  
  132.  
  133.