richard@ben.Jpl.Nasa.Gov (Conan the Barbarian) (03/20/90)
This is an answer to my own posting ( I did some more digging. Yes, there is a better reference than Stroustrup, Sun, AT&T, Hansen, and the Waite group for at least this topic. The Complete C++ Primer by Weiskamp and Flamig is more expansive. Though Stroustrup's book does have the information in a cryptic non-standard segment on pointers to member functions.) You should not pass the address of a member function to another routine unless the routine is written to support C++ and specifies an address to a member function rather than the address of a function. The method of passing the address is then moot. Due to the implementation feature of the hidden argument(this), C++ member function and C calls are not actually fully compatible in their use. This is not a flame. The use of the member function address does not make sense when separated from the class instance. (Yes I can think of a million exceptions also.) The member function would not fully operate as documented without the hidden argument. Yuck. That means the handler for a asynchronous server can not use C++ strategies unless you have all of the server source also. Double yuck. Who wants to re-write X, Motif, Xview, Sunview, etc? Triple yuck
kc@rna.UUCP (Kaare Christian) (03/21/90)
In article <1990Mar19.233906.23149@elroy.jpl.nasa.gov>, richard@ben.Jpl.Nasa.Gov (Conan the Barbarian) writes:
: This is not a flame. The use of the member function address
: does not make sense when separated from the class instance.
: (Yes I can think of a million exceptions also.)
: The member function would not fully operate as documented without
: the hidden argument.
:
: Yuck. That means the handler for a asynchronous server can
: not use C++ strategies unless you have all of the server
: source also. Double yuck. Who wants to re-write X, Motif,
: Xview, Sunview, etc? Triple yuck
This is an example of a situation where friends are useful. (See
ongoing discussion of friends.)
Kaare Christian
kc@rna.rockefeller.edu
jim@ocsmd.ocs.com (Jim Muth) (03/21/90)
In article <1990Mar19.233906.23149@elroy.jpl.nasa.gov> richard@ben.Jpl.Nasa.Gov (Conan the Barbarian) writes: >Yuck. That means the handler for a asynchronous server can >not use C++ strategies unless you have all of the server >source also. Double yuck. Who wants to re-write X, Motif, >Xview, Sunview, etc? Triple yuck Perhaps only a single yuck. A yuck and a half? There is a hack to get C++ member functions called from a system that uses C callbacks, as long as there is a way to hang a pointer off of the "server" object. For example, in say you wanted to define a SunView class, TkFrame, that could handle events: class TkFrame { public: TkFrame() { handle = 0; } Frame Create(); void EventHandler(Event*, void*); private: Frame handle; }; The trick is to associate a pointer to an instance of TkFrame with the SunView Frame, and to define an ordinary, non-member function as the callback: Frame TkFrame::Create() { handle = window_create(NULL, FRAME, WIN_CLIENT_DATA, this, WIN_EVENT_PROC, ::EventHandler, 0); return handle; } The ordinary function just yanks the pointer to a TkFrame out of the Frame and calls the member function: static void EventHandler(Frame handle, Event* event, void* arg) { TkFrame* frame = (TkFrame*) window_get(handle, WIN_CLIENT_DATA); frame->EventHandler(event, arg); } Not pretty, but it gets the job done. Jim Muth Online Computer Systems, Inc jim@ocsmd.ocs.com
robert@ireq.hydro.qc.ca (R.Meunier 8516) (10/02/90)
I'm trying to implement a stack objet with ptr to function as members. But i can't go through the compiler (SUN C++) Here is a part of the code, can someone point me out what is wrong. -------------------------------------------------------------------- #include <stream.h> class ST { void *data; void (*ptrFct)(void *); public: ST(void *, void (*)(void *)); void exec(); }; ST::ST(void *d, void (*ptr)(void *)) { data = d; ptrFct = ptr; } void ST::exec() { (*ptrFct)(data); } void foo1(int *a) { *a += 1; } void foo2(float *a) { *a += 1; } main() { int aa=10; float bb=100; void foo1(int *); void foo2(float *); ST a(&aa,foo1); ST b(&bb,foo2); a.exec(); a.exec(); } -------------------------------------------------------------------- I get those error message from the compiler: "p1.cc", line 44: error: bad argument 2 type for ST::ST(): void (*)(int *) ( void (*)(void *) expected) "p1.cc", line 45: error: bad argument 2 type for ST::ST(): void (*)(float *) ( void (*)(void *) expected) so i have not define the parameter by putting (...) like that -------------------------------------------------------------------- #include <stream.h> class ST { void *data; void (*ptrFct)(...); public: ST(void *, void (*)(...)); void exec(); }; ST::ST(void *d, void (*ptr)(...)) { data = d; ptrFct = ptr; } void ST::exec() { (*ptrFct)(data); } void foo1(int *a) { *a += 1; } void foo2(float *a) { *a += 1; } main() { int aa=10; float bb=100; void foo1(...); void foo2(...); ST a(&aa,foo1); ST b(&bb,foo2); a.exec(); a.exec(); } -------------------------------------------------------------------- With that code, i get ld: Undefined symbol _foo1() _foo2() because the compiler is trying to overload foo1 and foo2 since the parameter do not match. What should i do? P.S. In case you are wondering what i am trying to do, i am implemanting a small task library that will collect ptr to data and ptr to function and execute them later. The function are always of the form: Function(DATA *ptr) { } with function and DATA undefined by the task manager (declare as void *) -- ----------------------------------------------------------------------- Robert Meunier Institut de Recherche d'Hydro-Quebec Ingenieur 1800 Montee Ste-Julie, Varennes Internet: robert@ireq.hydro.qc.ca Qc, Canada, J3X 1S1
basti@orthogo.UUCP (Sebastian Wangnick) (10/18/90)
robert@ireq.hydro.qc.ca (R.Meunier 8516) writes: > I'm trying to implement a stack objet with ptr to function >as members. But i can't go through the compiler (SUN C++) Use the first example. Use typedef void (*ProcVoid) (void*) and cast to it: >main() >{ >int aa=10; >float bb=100; >void foo1(int *); >void foo2(float *); >ST a(&aa,ProcVoid(foo1)); >ST b(&bb,ProcVoid(foo2)); > a.exec(); > a.exec(); >} Hope that works, Sebastian Wangnick (basti@orthogo.uucp)