Calling C++ functions in C function through function pointers

Discussion in 'C Programming' started by D3|\\||\\|!$, Feb 25, 2008.

  1. D3|\\||\\|!$

    D3|\\||\\|!$ Guest

    Hi All!!

    I have a C++ program that uses callback funtions which are the private
    members of class. The code uses an API wrtiiten in C which supplies
    callback-setting functions that require pointers to these functions...
    The funtions wherein these API's callback-setting functions are
    called, are public members of the same class of which the callbacks
    are the private member.

    Now the API functions are generating compile errors since they cannot
    "understand" the C++ function pointers.





    Consider the sample code:
    class classname
    {
    public :

    /* Constructor for the class */
    classname ();

    /* Destructor for the class */
    ~classname ();

    /* Function calling API's callback setting function */
    ReturnType1 Call_SetCallback (ReturnType2 arg1, ReturnType3
    arg2,...);

    private :

    /* Callback to be passed through function pointer */
    Callback (ReturnType4 arg1, ReturnType5 arg2,...);
    };

    ReturnType1 classname :: Call_SetCallback (ReturnType6 arg1,
    ReturnType7 arg2,...)
    {
    /* PtrToCallback is a function pointer to Callback
    (ReturnType4 arg1, ReturnType5 arg2,...)*/
    SetCallback (&classname::Callback, void *arg);
    }




    OUTPUT on compilation:
    error Error C2664: 'SetCallback' : cannot convert parameter 1 from
    'ReturnType (__thiscall classname::* )(ReturnType4,ReturnType5)' to
    'ReturnType1' FilePath\filename.cpp LineNumber




    The same code had earlier been running perfectly fine as C code - I
    simply moved the concerned functions to their specific places in the
    aforesaid class and now its running into trouble.

    Could somebody please suggest me a possible workaround..?? I cannot
    export the concerned private callbacks outside the function or make
    them public...

    Warm Regards,
    D3|\||\|!$
     
    D3|\\||\\|!$, Feb 25, 2008
    #1
    1. Advertising

  2. D3|\\||\\|!$

    MisterE Guest

    somebody please suggest me a possible workaround..?? I cannot
    > export the concerned private callbacks outside the function or make
    > them public...


    This is offtopic here, try comp.lang.c.and.cpp
     
    MisterE, Feb 25, 2008
    #2
    1. Advertising

  3. D3|\||\|!$ wrote:

    > The same code had earlier been running perfectly fine as C code
    > - I simply moved the concerned functions to their specific
    > places in the aforesaid class and now its running into trouble.


    Even though this is the C newsgroup, I'm now giving you a heads
    up on C++: You CAN'T use class member functions for a C-style
    callback.

    Think about it: How would the callback function know, on which
    instance of the class to operate? The proper way to do it is to
    write a friend wrapper callback function, that takes a pointer
    to the class instance as parameter and calls the member function
    on that instance. If you want to keep it generic, let it take
    two parameters: The instance and a pointer-to-member (this is
    different from a ordinary C pointer, as this is more an offset,
    than a absolute pointer) in form of void*, typecast those to the
    proper types and call it.

    class foo
    {
    int bar();
    friend int foo_bar_wrapper(void * i_);
    };

    int foo_bar_wrapper(void * i_)
    {
    foo * instance = dynamic_cast<foo*> i_;
    return instance->bar();
    }

    void register_callback(int(*p)(), void * data);

    I'm too lazy, to give an example of the pointer-to-member method
    here. Personally I actually discourage it's use, as it's prone
    to introduce a lot of nasty to track down bugs.

    Wolfgang Draxinger
    --
    E-Mail address works, Jabber: , ICQ: 134682867
     
    Wolfgang Draxinger, Feb 25, 2008
    #3
  4. D3|\\||\\|!$

    Default User Guest

    MisterE wrote:

    > somebody please suggest me a possible workaround..?? I cannot
    > > export the concerned private callbacks outside the function or make
    > > them public...

    >
    > This is offtopic here, try comp.lang.c.and.cpp


    There is no such newsgroup.




    Brian
     
    Default User, Feb 25, 2008
    #4
  5. "D3|\||\|!$" <> writes:
    > I have a C++ program that uses callback funtions which are the private
    > members of class. The code uses an API wrtiiten in C which supplies
    > callback-setting functions that require pointers to these functions...
    > The funtions wherein these API's callback-setting functions are
    > called, are public members of the same class of which the callbacks
    > are the private member.
    >
    > Now the API functions are generating compile errors since they cannot
    > "understand" the C++ function pointers.

    [...]

    As it happens, C++ provides mechanisms for calls between C and C++
    programs; C does not. So your question is more suitable for
    comp.lang.c++.

    Ordinary C-to-C++ and C++-to-C function calls are covered in the C++
    FAQ. Member functions are going to be trickier; consider a wrapper.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 25, 2008
    #5
  6. D3|\\||\\|!$

    Guest

    On Feb 25, 2:38 am, "D3|\\||\\|!$" <> wrote:
    > Hi All!!
    >
    > I have a C++ program that uses callback funtions which are the private
    > members of class. The code uses an API wrtiiten in C which supplies
    > callback-setting functions that require pointers to these functions...
    > The funtions wherein these API's callback-setting functions are
    > called, are public members of the same class of which the callbacks
    > are the private member.
    >
    > Now the API functions are generating compile errors since they cannot
    > "understand" the C++ function pointers.
    >
    > Consider the sample code:
    > class classname
    > {
    >     public :
    >
    >         /* Constructor for the class */
    >         classname ();
    >
    >         /* Destructor for the class */
    >         ~classname ();
    >
    >        /* Function calling API's callback setting function */
    >        ReturnType1 Call_SetCallback (ReturnType2 arg1, ReturnType3
    > arg2,...);
    >
    >     private :
    >
    >         /* Callback to be passed through function pointer */
    >         Callback (ReturnType4 arg1, ReturnType5 arg2,...);
    >
    > };
    >
    > ReturnType1 classname :: Call_SetCallback (ReturnType6 arg1,
    > ReturnType7 arg2,...)
    > {
    >         /* PtrToCallback is a function pointer to Callback
    > (ReturnType4 arg1, ReturnType5 arg2,...)*/
    >         SetCallback (&classname::Callback, void *arg);
    >
    > }
    >
    > OUTPUT on compilation:
    > error Error C2664: 'SetCallback' : cannot convert parameter 1 from
    > 'ReturnType (__thiscall classname::* )(ReturnType4,ReturnType5)' to
    > 'ReturnType1'   FilePath\filename.cpp   LineNumber
    >
    > The same code had earlier been running perfectly fine as C code - I
    > simply moved the concerned functions to their specific places in the
    > aforesaid class and now its running into trouble.
    >
    > Could somebody please suggest me a possible workaround..?? I cannot
    > export the concerned private callbacks outside the function or make
    > them public...
    >
    > Warm Regards,
    > D3|\||\|!$


    This is a very common problem when using, for example, GUI toolkits
    written in C. The easiest solution is to creeate a static function
    in your class, where one of the parameters for that function is
    the 'this' pointer.

    An example using X/Motif:

    In your C++ class header:
    class MyClass {
    public:
    static void MyStaticFunction( Widget, XtPointer, XtPointer);
    protected:
    void MyRealFunction(...);
    +

    In your C++ code:
    // Xt ships the 4th paramater as the clientData to
    // callback functions
    XtAddCallback( widget, XmNsomeCallback, MyStaticFunction, this );

    Then, elsewhere in your C++ code, define the static function:

    void MyStaticFunction( Widget w, XtPointer clientData, XtPointer
    callData)
    (
    MyClass *me = (MyClass *)callData;
    me->MyRealFunction(...)
    )

    --
    Fred Kleinschmidt
     
    , Feb 25, 2008
    #6
  7. D3|\\||\\|!$

    Ian Collins Guest

    wrote:
    >
    > This is a very common problem when using, for example, GUI toolkits
    > written in C. The easiest solution is to creeate a static function
    > in your class, where one of the parameters for that function is
    > the 'this' pointer.
    >
    > An example using X/Motif:
    >
    > In your C++ class header:
    > class MyClass {
    > public:
    > static void MyStaticFunction( Widget, XtPointer, XtPointer);


    While OT, this isn't strictly correct. The only type of function you
    should pass to C from C++ is a function declared with extern "C"
    linkage. Static member functions have C++ linkage, so use a friend instead.

    A decent C++ compiler will issues a diagnostic if you pass anything else.

    --
    Ian Collins.
     
    Ian Collins, Feb 25, 2008
    #7
  8. Ian Collins wrote:

    > wrote:
    >>
    >> This is a very common problem when using, for example, GUI
    >> toolkits written in C. The easiest solution is to creeate a
    >> static function in your class, where one of the parameters for
    >> that function is the 'this' pointer.
    >>
    >> An example using X/Motif:
    >>
    >> In your C++ class header:
    >> class MyClass {
    >> public:
    >> static void MyStaticFunction( Widget, XtPointer,
    >> XtPointer);

    >
    > While OT, this isn't strictly correct. The only type of
    > function you should pass to C from C++ is a function declared
    > with extern "C"
    > linkage. Static member functions have C++ linkage, so use a
    > friend instead.


    Could it be, that you mistake linkage for registering a callback,
    which are completely different things?

    extern "C" means nothing else, than to disable name mangling,
    which is the only difference between C and C++ linkage. If you
    know the mangled name of a C++ function you could as well
    declare that for use with C. The whole idea behind extern "C" is
    to disable it. It also means, that you can't overload functions
    in a extern "C" block, as overloading is implemented through
    name mangling.

    As long no class instances are concerned the calling convention
    for C++ functions is the same as for C. A static member function
    is technically an ordinary function, with the additional twist,
    that it lives in the class' namespace and thus has access to
    protected and private members of any instance of that class.
    Remember that C++ restricts access to class members at compile
    time.

    Wolfgang Draxinger
    --
    E-Mail address works, Jabber: , ICQ: 134682867
     
    Wolfgang Draxinger, Feb 25, 2008
    #8
  9. D3|\\||\\|!$

    Ian Collins Guest

    Wolfgang Draxinger wrote:
    > Ian Collins wrote:
    >
    >> wrote:
    >>> This is a very common problem when using, for example, GUI
    >>> toolkits written in C. The easiest solution is to creeate a
    >>> static function in your class, where one of the parameters for
    >>> that function is the 'this' pointer.
    >>>
    >>> An example using X/Motif:
    >>>
    >>> In your C++ class header:
    >>> class MyClass {
    >>> public:
    >>> static void MyStaticFunction( Widget, XtPointer,
    >>> XtPointer);

    >> While OT, this isn't strictly correct. The only type of
    >> function you should pass to C from C++ is a function declared
    >> with extern "C"
    >> linkage. Static member functions have C++ linkage, so use a
    >> friend instead.

    >
    > Could it be, that you mistake linkage for registering a callback,
    > which are completely different things?
    >

    No, I've been putting people straight on this for years over on c.l.c++.

    > extern "C" means nothing else, than to disable name mangling,
    > which is the only difference between C and C++ linkage.


    There is nothing in either standard to say that. A C++ implementation
    is free to use a different calling convention from C if it chooses to do
    so. That's why the linkage specifier is there in the language.
    >
    > As long no class instances are concerned the calling convention
    > for C++ functions is the same as for C.


    As I said, it might be and typically is, but there is no guarantee.

    --
    Ian Collins.
     
    Ian Collins, Feb 25, 2008
    #9
  10. D3|\\||\\|!$

    Gerry Ford Guest

    "Ian Collins" <> wrote in message
    news:...
    > Wolfgang Draxinger wrote:


    >> Could it be, that you mistake linkage for registering a callback,
    >> which are completely different things?
    >>

    > No, I've been putting people straight on this for years over on c.l.c++.
    >
    >> extern "C" means nothing else, than to disable name mangling,
    >> which is the only difference between C and C++ linkage.

    >
    > There is nothing in either standard to say that. A C++ implementation
    > is free to use a different calling convention from C if it chooses to do
    > so. That's why the linkage specifier is there in the language.
    >>
    >> As long no class instances are concerned the calling convention
    >> for C++ functions is the same as for C.

    >
    > As I said, it might be and typically is, but there is no guarantee.
    >
    > --
    > Ian Collins.


    I think this question was multiposted to clc++, and through some strange
    planetary alignment, I'm reading both forums now. There is no clc.and.cpp,
    so don't waste your time like Brian and I did.

    I think if OP does what Ian suggests, he'll get farther along in his
    project.

    --
    Gerry Ford

    "Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
    beziehend.
     
    Gerry Ford, Feb 25, 2008
    #10
  11. D3|\\||\\|!$

    Default User Guest

    Gerry Ford wrote:


    > I think this question was multiposted to clc++, and through some
    > strange planetary alignment, I'm reading both forums now. There is
    > no clc.and.cpp, so don't waste your time like Brian and I did.


    Well, Brian didn't waste his time. He knew that there was no such
    group. Had it been an alt group, then lookup would have been required.

    There is alt.comp.lang.learn.c-c++, which might be what MisterE was
    thinking of.



    Brian
     
    Default User, Feb 25, 2008
    #11
  12. D3|\\||\\|!$

    Gerry Ford Guest

    "Default User" <> wrote in message
    news:...
    > Gerry Ford wrote:
    >
    >
    >> I think this question was multiposted to clc++, and through some
    >> strange planetary alignment, I'm reading both forums now. There is
    >> no clc.and.cpp, so don't waste your time like Brian and I did.

    >
    > Well, Brian didn't waste his time. He knew that there was no such
    > group. Had it been an alt group, then lookup would have been required.

    So what requires looking this up? (The dangers of passive voice, or is it
    mood?) :)
    --
    Gerry Ford

    "Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
    beziehend.
     
    Gerry Ford, Feb 25, 2008
    #12
  13. Ian Collins wrote:

    > Wolfgang Draxinger wrote:
    >> Ian Collins wrote:
    >>
    >>> wrote:
    >>>> This is a very common problem when using, for example, GUI
    >>>> toolkits written in C. The easiest solution is to creeate a
    >>>> static function in your class, where one of the parameters
    >>>> for that function is the 'this' pointer.
    >>>>
    >>>> An example using X/Motif:
    >>>>
    >>>> In your C++ class header:
    >>>> class MyClass {
    >>>> public:
    >>>> static void MyStaticFunction( Widget, XtPointer,
    >>>> XtPointer);
    >>> While OT, this isn't strictly correct. The only type of
    >>> function you should pass to C from C++ is a function declared
    >>> with extern "C"
    >>> linkage. Static member functions have C++ linkage, so use a
    >>> friend instead.

    >>
    >> Could it be, that you mistake linkage for registering a
    >> callback, which are completely different things?
    >>

    > No, I've been putting people straight on this for years over on
    > c.l.c++.
    >
    >> extern "C" means nothing else, than to disable name mangling,
    >> which is the only difference between C and C++ linkage.

    >
    > There is nothing in either standard to say that. A C++
    > implementation is free to use a different calling convention
    > from C if it chooses to do
    > so. That's why the linkage specifier is there in the language.


    Umm, I don't see any reason, why linkage should be in any way
    related to calling convention. The OP asked about callbacks,
    which means: The address of a function (actually the point in
    memory, where the function's code begins) is stored, so that it
    can be called if something funny happens. Calling convention
    OTOH describes, what preparations must be done, before
    instructing the CPU to enter that function. And let's face it:
    In C the calling convention is not supplied by the address-of
    operator of the function, but by the pointer the address is
    stored in. It's perfectly possible to pass a pascall-calling
    convention function pointer for callback, but as soon the
    callback is entered, the program will crash. A good compiler
    will (hopefully) emit a warning about type mismatch.

    Yes at the very low level this is related to linkage, but don't
    lets get to academic on this topic. The fact is, that all C++
    implementations (compilers) share their condebase with a plain C
    compiler and thus will share the C calling convention.
    Practically this reduces 'extern "C"' to a name mangling
    disabler, and in some textbooks on C++ it's actually described
    (wrongly from the academic, but correct from the practical point
    of view) as such.

    > As I said, it might be and typically is, but there is no
    > guarantee.


    No there isn't of course. This is IMHO a big drawback on C++ --
    that it has no ABI standard I mean. I'm not aware of any
    implementation, that has a calling convention for C++ different
    from C. Of course, if you can name me one (and I mean a
    implementation of C++ that's in widespread use, i.e. more than
    10 users) then that's a different story.

    This is the main reason, that I turned my back on C++. The lack
    of a real ABI standard makes it impossible to have sane ways to
    implement binary module systems. Everything is alright, as long
    the compilers agree on how to do things, but if not... Don't get
    me started on this. For the same reason I also don't use Qt
    anymore, but switched to GTK+.

    Wolfgang Draxinger
    --
    E-Mail address works, Jabber: , ICQ: 134682867
     
    Wolfgang Draxinger, Feb 25, 2008
    #13
  14. D3|\\||\\|!$

    Gerry Ford Guest

    "Wolfgang Draxinger" <> wrote in message
    news:...
    > Ian Collins wrote:
    >
    >> Wolfgang Draxinger wrote:


    [...]
    >>> extern "C" means nothing else, than to disable name mangling,
    >>> which is the only difference between C and C++ linkage.

    >>
    >> There is nothing in either standard to say that. A C++
    >> implementation is free to use a different calling convention
    >> from C if it chooses to do
    >> so. That's why the linkage specifier is there in the language.

    >
    > Umm, I don't see any reason, why linkage should be in any way


    >> As I said, it might be and typically is, but there is no
    >> guarantee.

    >
    > No there isn't of course. This is IMHO a big drawback on C++ --

    snip

    When C sharp appeared, I conjectured the future existence of c flat.

    Maybe C++-- might be good shorthand that includes c, c plusplus, and the
    most recent MS flavor.


    --
    Gerry Ford

    "Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
    beziehend.
     
    Gerry Ford, Feb 25, 2008
    #14
  15. D3|\\||\\|!$

    Default User Guest

    Gerry Ford wrote:

    >
    > "Default User" <> wrote in message
    > news:...


    > > Well, Brian didn't waste his time. He knew that there was no such
    > > group. Had it been an alt group, then lookup would have been
    > > required.


    > So what requires looking this up? (The dangers of passive voice, or
    > is it mood?) :)


    Google Groups, usually.





    Brian
     
    Default User, Feb 26, 2008
    #15
  16. D3|\\||\\|!$

    Gerry Ford Guest

    "Default User" <> wrote in message
    news:...
    > Gerry Ford wrote:
    >
    >>
    >> "Default User" <> wrote in message
    >> news:...

    >
    >> > Well, Brian didn't waste his time. He knew that there was no such
    >> > group. Had it been an alt group, then lookup would have been
    >> > required.

    >
    >> So what requires looking this up? (The dangers of passive voice, or
    >> is it mood?) :)

    >
    > Google Groups, usually.
    >
    >
    >
    >
    >
    > Brian
    >


    I get it. Groups for people who don't get group theory.

    --
    Gerry Ford

    "Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
    beziehend.
     
    Gerry Ford, Feb 26, 2008
    #16
  17. D3|\\||\\|!$

    Ian Collins Guest

    Wolfgang Draxinger wrote:
    > Ian Collins wrote:
    >


    >> There is nothing in either standard to say that. A C++
    >> implementation is free to use a different calling convention
    >> from C if it chooses to do
    >> so. That's why the linkage specifier is there in the language.

    >

    <snip>
    >
    >> As I said, it might be and typically is, but there is no
    >> guarantee.

    >
    > No there isn't of course. This is IMHO a big drawback on C++ --


    The potential difference in calling convention is between C and C++.
    The two are unique languages, they may use different calling conventions
    on the same platform. C++ provides extern "C" as a means of generating
    functions usable by C (and by extension, other C++ compilers on that
    platform).

    --
    Ian Collins.
     
    Ian Collins, Feb 26, 2008
    #17
  18. D3|\\||\\|!$

    Default User Guest

    Gerry Ford wrote:

    >
    > "Default User" <> wrote in message
    > news:...


    > > > So what requires looking this up? (The dangers of passive voice,
    > > > or is it mood?) :)

    > >
    > > Google Groups, usually.


    > I get it. Groups for people who don't get group theory.


    No idea what this is supposed to mean.




    Brian
     
    Default User, Feb 26, 2008
    #18
  19. "Default User" <> writes:
    > Gerry Ford wrote:
    >> "Default User" <> wrote in message
    >> news:...
    >> > > So what requires looking this up? (The dangers of passive voice,
    >> > > or is it mood?) :)
    >> >
    >> > Google Groups, usually.

    >
    >> I get it. Groups for people who don't get group theory.

    >
    > No idea what this is supposed to mean.


    I suggest that it's time to sit back in silence and wait for "Gerry
    Ford" to start making sense. If he never does, so be it.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Feb 26, 2008
    #19
  20. D3|\\||\\|!$

    Default User Guest

    Keith Thompson wrote:

    > "Default User" <> writes:
    > > Gerry Ford wrote:
    > >> "Default User" <> wrote in message
    > >> news:...
    > >> > > So what requires looking this up? (The dangers of passive

    > voice, >> > > or is it mood?) :)
    > >> >
    > >> > Google Groups, usually.

    > >
    > >> I get it. Groups for people who don't get group theory.

    > >
    > > No idea what this is supposed to mean.

    >
    > I suggest that it's time to sit back in silence and wait for "Gerry
    > Ford" to start making sense. If he never does, so be it.


    Yeah, I'd already replied before I read some of his other . . .
    "unique" contributions.




    Brian
     
    Default User, Feb 27, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Timothy Madden
    Replies:
    3
    Views:
    510
    Timothy Madden
    Dec 29, 2004
  2. S?ren Gammelmark
    Replies:
    1
    Views:
    1,989
    Eric Sosman
    Jan 7, 2005
  3. Marc Thrun
    Replies:
    15
    Views:
    884
    Tim Rentsch
    Oct 4, 2005
  4. D3|\\||\\|!$
    Replies:
    3
    Views:
    3,558
    Ian Collins
    Feb 25, 2008
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    738
Loading...

Share This Page