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.edujim@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)