Topic: typedef void (SomeClass::*)() MemeberPtr; not legal?


Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/09/20
Raw View
Mike Austin <cut-m.austin@ix.netcom.com> writes:

[ copied from subject line:
    typedef void (SomeClass::*)() MemeberPtr;
]

>Is this legal?  Is there any reason not to be?

If you intend for MemeberPtr to be a typedef for a pointer to
member function class SomeClass, the syntax is wrong. It should be

    typedef void (SomeClass::*MemeberPtr)() ;

With this syntax, MemeberPtr is the name of a type that represents
a member function of SomeClass that takes no parameters and
returns void.

>Should I also be able to cast it from a void *?

You cannot cast a pointer-to-member to or from a void*. A pointer
to member is a different kind of thing than an ordinary data pointer.
The only casts allowed with pointer-to-member involve casting
to a similar member of a base or derived class.

>This is used for loading a member function's address dynamically with
>dlsym().

If dlsym() is the same function specified by XOpen, it is declared
to return a void*, but can return either a data pointer or a
function pointer. It cannot return a pointer to a class member
function, so the typedef will be of no use in conjunction with dlsym.

Which brings us to the mis-specification of dlsym in XOpen. It is
not valid in either C or C++ to cast a void* to or from a function
pointer. Since most C compilers don't complain about the cast
(except possibly in strict-conformance mode), the XOpen people
might not have been aware of the invalid specification for dlsym.

Function dlsym should really be two functions, one returning a
void* and the other returning some convenient pointer-to-function
type. Since to use dlsym you must know at the point of the call
whether the return value points to data or to a function, it is
no hardship on the programmer to have to specify the correct
function name.

--
Steve Clamage, stephen.clamage@sun.com


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Mike Austin <cut-m.austin@ix.netcom.com>
Date: 1999/09/20
Raw View
Thanks for the correction.  What I'm doing is creating a pointer to a member
function in the shared library.  From there, I am using dlsym to get this
address.  I already have a pointer to the object so I can call
(obj->*memberPtr)().  Actually, I'm not sure I can extern "C" this anyway.

in lib:
memberPtr = &SomeClass::SomeMethod;

Mike

Steve Clamage wrote:

> Mike Austin <cut-m.austin@ix.netcom.com> writes:
>
> [ copied from subject line:
>     typedef void (SomeClass::*)() MemeberPtr;
> ]
>
> >Is this legal?  Is there any reason not to be?
>
> If you intend for MemeberPtr to be a typedef for a pointer to
> member function class SomeClass, the syntax is wrong. It should be
>
>     typedef void (SomeClass::*MemeberPtr)() ;
>
> With this syntax, MemeberPtr is the name of a type that represents
> a member function of SomeClass that takes no parameters and
> returns void.
>
> >Should I also be able to cast it from a void *?
>
> You cannot cast a pointer-to-member to or from a void*. A pointer
> to member is a different kind of thing than an ordinary data pointer.
> The only casts allowed with pointer-to-member involve casting
> to a similar member of a base or derived class.
>
> >This is used for loading a member function's address dynamically with
> >dlsym().
>
> If dlsym() is the same function specified by XOpen, it is declared
> to return a void*, but can return either a data pointer or a
> function pointer. It cannot return a pointer to a class member
> function, so the typedef will be of no use in conjunction with dlsym.
>
> Which brings us to the mis-specification of dlsym in XOpen. It is
> not valid in either C or C++ to cast a void* to or from a function
> pointer. Since most C compilers don't complain about the cast
> (except possibly in strict-conformance mode), the XOpen people
> might not have been aware of the invalid specification for dlsym.
>
> Function dlsym should really be two functions, one returning a
> void* and the other returning some convenient pointer-to-function
> type. Since to use dlsym you must know at the point of the call
> whether the return value points to data or to a function, it is
> no hardship on the programmer to have to specify the correct
> function name.
>
> --
> Steve Clamage, stephen.clamage@sun.com
>
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/09/21
Raw View
Steve Clamage wrote:
>
> Mike Austin <cut-m.austin@ix.netcom.com> writes:
>
> [ copied from subject line:
>     typedef void (SomeClass::*)() MemeberPtr;
> ]
>
> >Is this legal?  Is there any reason not to be?
>
> If you intend for MemeberPtr to be a typedef for a pointer to
> member function class SomeClass, the syntax is wrong. It should be
>
>     typedef void (SomeClass::*MemeberPtr)() ;
>
> With this syntax, MemeberPtr is the name of a type that represents
> a member function of SomeClass that takes no parameters and
> returns void.
>
> >Should I also be able to cast it from a void *?
>
> You cannot cast a pointer-to-member to or from a void*. A pointer
> to member is a different kind of thing than an ordinary data pointer.
> The only casts allowed with pointer-to-member involve casting
> to a similar member of a base or derived class.
>
> >This is used for loading a member function's address dynamically with
> >dlsym().
>
> If dlsym() is the same function specified by XOpen, it is declared
> to return a void*, but can return either a data pointer or a
> function pointer. It cannot return a pointer to a class member
> function, so the typedef will be of no use in conjunction with dlsym.
>
> Which brings us to the mis-specification of dlsym in XOpen. It is
> not valid in either C or C++ to cast a void* to or from a function
> pointer. Since most C compilers don't complain about the cast
> (except possibly in strict-conformance mode), the XOpen people
> might not have been aware of the invalid specification for dlsym.
>
> Function dlsym should really be two functions, one returning a
> void* and the other returning some convenient pointer-to-function
> type. Since to use dlsym you must know at the point of the call
> whether the return value points to data or to a function, it is
> no hardship on the programmer to have to specify the correct
> function name.

Well, for C++, the ideal solution would probably be

template<typename T> T* dlsym_cpp(char const* symbol);
                                  // or maybe string

This could also do the name mangling on symbols (so for
example dlsym_cpp<void(int, char*)>("foo") would load the
symbol "foo__Fipc" instead of just "foo").

C functions would then need an extra typedef:

extern "C" void c_func();
c_func* pfoo = dlsym_cpp<c_func>("foo"); // loads symbol "foo"


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/09/21
Raw View
In article <37E69152.6A9F3CC1@ix.netcom.com>,
  cut-m.austin@ix.netcom.com wrote:

> Thanks for the correction.  What I'm doing is creating a pointer to a
> member function in the shared library.  From there, I am using dlsym
> to get this address.  I already have a pointer to the object so I can
> call (obj->*memberPtr)().  Actually, I'm not sure I can extern "C"
> this anyway.

> in lib:
> memberPtr = &SomeClass::SomeMethod;

What dlsym will give you is the *address* of memberPtr (as a void*).  So
what you need is a pointe to member pointer, e.g.:

    typedef void (MyClass::*PtrToMemberFnc)() ;

    PtrToMemberFnc*   ppmf = static_cast< PtrToMemberFnc* >( dlsym() ) ;
    //  With *ppmf to get the actual pointer to member function.

--
James Kanze                   mailto: James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/09/21
Raw View
Mike Austin <cut-m.austin@ix.netcom.com> writes:

>Thanks for the correction.  What I'm doing is creating a pointer to a member
>function in the shared library.  From there, I am using dlsym to get this
>address.  I already have a pointer to the object so I can call
>(obj->*memberPtr)().  Actually, I'm not sure I can extern "C" this anyway.

>in lib:
>memberPtr = &SomeClass::SomeMethod;

Function dlsym is supposed to return the address of a symbol.
If memberPtr is a symbol in the dynamic library, you can get
its address as a void*, then cast the address to a pointer
to member-pointer of the appropriate type.

    class SomeClass { ... };
    typedef int (SomeClass::*mfptr)(int);

    mfptr mp = *static_cast<mfptr*>(dlsym("memberPtr"));
    SomeClass* obj = ...;
    int k = (obj->mp)(42);


But you won't be able to get an arbitrary pointer-to-member from
the dynamic library using dlsym. That is, attempts like
 dlsym("SomeClass::SomeMethod")
 dlsym("mangled_name_of_Someclass_SomeMethod")
won't work.

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Mike Austin <cut-m.austin@ix.netcom.com>
Date: 1999/09/20
Raw View
Is this legal?  Is there any reason not to be?  Should I also be able to
cast it from a void *?

This is used for loading a member function's address dynamically with
dlsym().  I'm using gnu 2.7.?


Mike



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]