function pointer

Discussion in 'C++' started by David Hill, Jun 24, 2003.

  1. David Hill

    David Hill Guest

    Hello -
    I am using a library that takes a function pointer as an argument. Is the code below not possible?


    int library_func(void (*func)(int, short, void *));


    I am trying to do this...

    class Test {
    public:
    Test();
    void a(int, short, void *);
    void loop(void);
    };

    Test::Test()
    {
    }

    void Test::a(int a, short b, void *c)
    {
    }

    void Server::loop(void)
    {
    void (*func)(int, short, void *) = a;

    library_function(func);
    }

    int main(void)
    {
    Test s;
    s.loop();

    return (0);
    }
    David Hill, Jun 24, 2003
    #1
    1. Advertising

  2. David Hill

    Ron Natalie Guest

    "David Hill" <> wrote in message news:...
    > Hello -
    > I am using a library that takes a function pointer as an argument. Is the code below not possible?
    >
    > void (*func)(int, short, void *) = a;
    >


    It is not possible. Member functions are different than regular functions.
    You can't convert between the two. What object is the member function
    going to be invoked on if you only have the member address?

    If you can't change the interface to the library, you're going to have to wrap the
    member function call in an ordinary function. You can squirrel away the pointer
    to member and "this" pointer in that extra void* operand I suspect.
    Ron Natalie, Jun 24, 2003
    #2
    1. Advertising

  3. >
    >
    > void Server::loop(void)
    > {
    > // void (*func)(int, short, void *) = a;


    it shud be:
    void (*func)(int, short, void *) = &Test::a;
    Chandra Shekhar Kumar, Jun 24, 2003
    #3
  4. David Hill

    Jeremy Guest

    "Ron Natalie" <> wrote in message
    news:...
    >
    > "David Hill" <> wrote in message

    news:...
    > > Hello -
    > > I am using a library that takes a function pointer as an argument. Is

    the code below not possible?
    > >
    > > void (*func)(int, short, void *) = a;
    > >

    >
    > It is not possible. Member functions are different than regular

    functions.
    > You can't convert between the two. What object is the member function
    > going to be invoked on if you only have the member address?
    >
    > If you can't change the interface to the library, you're going to have to

    wrap the
    > member function call in an ordinary function. You can squirrel away the

    pointer
    > to member and "this" pointer in that extra void* operand I suspect.
    >


    What does that mean (You can squirrel away the pointer to member and "this"
    pointer in that extra void* operand I suspect)?
    (i'm a newb, sorry)
    Jeremy, Jun 24, 2003
    #4
  5. Declare a member function of you're object as static. This will keep it from
    getting a "this" pointer, and you'll be able to point a C style function
    pointer at it. Pass this to you're library. Additionally (and this is the
    squirling away part), most of the time when you're doing this, the call that
    tells the library where the function to callback is also includes a void*
    that you can pass whatever you want to. This void* gets passed to the
    function when it is called. Since you passed a static function, you have no
    this pointer, and no way to get at the object. Pass the "this" pointer into
    that void*, cast it into the object (using dynamic_cast<> for safety) inside
    the callback function, and you can now get at you're object.

    Nifty no?

    Tony


    "Jeremy" <> wrote in message
    news:jH1Ka.113491$...
    > "Ron Natalie" <> wrote in message
    > news:...
    > >
    > > "David Hill" <> wrote in message

    > news:...
    > > > Hello -
    > > > I am using a library that takes a function pointer as an argument. Is

    > the code below not possible?
    > > >
    > > > void (*func)(int, short, void *) = a;
    > > >

    > >
    > > It is not possible. Member functions are different than regular

    > functions.
    > > You can't convert between the two. What object is the member function
    > > going to be invoked on if you only have the member address?
    > >
    > > If you can't change the interface to the library, you're going to have

    to
    > wrap the
    > > member function call in an ordinary function. You can squirrel away

    the
    > pointer
    > > to member and "this" pointer in that extra void* operand I suspect.
    > >

    >
    > What does that mean (You can squirrel away the pointer to member and

    "this"
    > pointer in that extra void* operand I suspect)?
    > (i'm a newb, sorry)
    >
    >
    Tony Di Croce, Jun 25, 2003
    #5
  6. David Hill

    Pete Becker Guest

    Tony Di Croce wrote:
    >
    > Declare a member function of you're object as static. This will keep it from
    > getting a "this" pointer, and you'll be able to point a C style function
    > pointer at it.


    Well, maybe. But not portably. Member functions have C++ linkage, and a
    C library expects functions with C linkage. Most compilers don't
    distinguish between the two, so you can get away with doing this. But
    it's better to use a non-member function and mark it extern "C".

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Jun 25, 2003
    #6
  7. Chandra Shekhar Kumar wrote in news::

    >>
    >>
    >> void Server::loop(void)
    >> {
    >> // void (*func)(int, short, void *) = a;

    >
    > it shud be:
    > void (*func)(int, short, void *) = &Test::a;
    >
    >


    Not true, there is no conversion from member-function-pointer
    to function-pointer, or from member-pointer to pointer for
    that matter.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Jun 25, 2003
    #7
  8. "Chandra Shekhar Kumar" <> wrote in message
    news:...
    > >
    > >
    > > void Server::loop(void)
    > > {
    > > // void (*func)(int, short, void *) = a;

    >
    > it shud be:
    > void (*func)(int, short, void *) = &Test::a;
    >


    No, this should not work.
    My compiler issues this error message:
    "'initializing' : cannot convert from 'void (__thiscall
    Test::*)(int,short,void *)' to 'void (__cdecl *)(int,short,void *)'
    There is no context in which this conversion is possible."
    Josephine Schafer, Jun 25, 2003
    #8
  9. David Hill

    Ron Natalie Guest

    "Chandra Shekhar Kumar" <> wrote in message news:...
    > >
    > >
    > > void Server::loop(void)
    > > {
    > > // void (*func)(int, short, void *) = a;

    >
    > it shud be:
    > void (*func)(int, short, void *) = &Test::a;
    >

    It still won't work. You can't assign a pointer to member to pointer to (non-member) function
    no matter how you qualify it.
    Ron Natalie, Jun 25, 2003
    #9
  10. David Hill

    Ron Natalie Guest

    "Jeremy" <> wrote in message news:jH1Ka.113491$...
    > "Ron Natalie" <> wrote in message
    > news:...
    > >
    > > "David Hill" <> wrote in message

    > news:...
    > > > Hello -
    > > > I am using a library that takes a function pointer as an argument. Is

    > the code below not possible?
    > > >
    > > > void (*func)(int, short, void *) = a;
    > > >

    > >
    > > It is not possible. Member functions are different than regular

    > functions.
    > > You can't convert between the two. What object is the member function
    > > going to be invoked on if you only have the member address?
    > >
    > > If you can't change the interface to the library, you're going to have to

    > wrap the
    > > member function call in an ordinary function. You can squirrel away the

    > pointer
    > > to member and "this" pointer in that extra void* operand I suspect.
    > >

    >
    > What does that mean (You can squirrel away the pointer to member and "this"
    > pointer in that extra void* operand I suspect)?
    > (i'm a newb, sorry)
    >


    struct WrapperHelper {
    Test* obj;
    void (TEST::*fp)(int, short, void*);
    void* arg;
    } ;

    void Wrapper(int i, short s, void* vp) {
    WrapperHelper* sp = static_cast<WrapperHelper*>(vp);
    (sp->*func)(i, s, sp->arg);
    delete sp;
    }

    void Test::SetupWrapper() {
    WrapperHelper* sp = new WrapperHelper;
    sp->obj = this;
    sp->fp = &Test::func;
    sp->arg = whatever.
    library_func(&Wrapper, sp);
    }
    Ron Natalie, Jun 25, 2003
    #10
    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. glen stark
    Replies:
    2
    Views:
    687
    Ron Natalie
    Oct 10, 2003
  2. Fraser Ross
    Replies:
    4
    Views:
    1,023
    Fraser Ross
    Aug 14, 2004
  3. murgan
    Replies:
    6
    Views:
    4,832
    Thad Smith
    Dec 21, 2005
  4. Vijai Kalyan
    Replies:
    4
    Views:
    689
    Vijai Kalyan
    Nov 8, 2005
  5. Replies:
    3
    Views:
    297
    Philip Potter
    Apr 11, 2008
Loading...

Share This Page