Thread: member fn pointer -> fn pointer?

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    519

    member fn pointer -> fn pointer?

    Hi,
    the last day i read through things like boost::bind, mem_fun, boost::function and google to find a proper way to pass a member function pointer to a function that takes a c-function pointer.

    In my imagination I pass a member function pointer together with an object to some function, and it returns a c-function pointer, with the object address hard coded in it somehow.

    Code:
    struct A
    {
        void mem()
       {}
    };
    
    
    void c_api_function( void(*fn)() )
    {
        // do something with fn
    }
    
    int main()
    {
        A a;
        c_api_function(); // somehow pass &A::f of a
    }
    so I'm looking for anything that is able to directly pass a's member f to the c-funtion.


    nothing I read about seems to do this. I know the workarounds proposed in the c++ faq. but isn't there not a more elegant solution?

    The closest thing I found is the thing the first poster mentioned here:
    http://groups.google.com/group/comp....52115c6f839238
    But I'm not feeling to be at the level of understanding c++ to use that.

    Thanks for your ideas!
    Last edited by pheres; 09-29-2007 at 05:00 AM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What you want to do isn't trivial. If you can make your function pointer take an arbitrary pointer as an argument, you could make a pointer to an object into a void pointer, and then cast it back to the object pointer in a standard function.

    Anything else will be some variation on this.

    The way that member functions know which object they are operating on is by being passed a "object *this" as a hidden first argument to the function, so the call to a member function is different from a "normal" function - and there's no way around that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Thank's matsp.
    We have all that legacy c-api and on the other side our c++ classes. In my view such a conversion is really needed by people (and searching google shows that clearly). And the problem seems known to the creators of the c++ language: there are adapters in the stl to transform member functions to functors so they can be used in stl algorithms, which can't handle algorithms in member functions directly.
    I doesn't understand, why the language isn't improved to address the pointer conversion too, so that c-api can conveniently used in the world of OOP ...

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And how do you suppose that should be done?

    Adding a wrapper layer is really the only way to achieve that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Location
    Houston, TX
    Posts
    5
    boost::bind is the way I use to do it.. sorry dont have time right now.. to post the details. check out the boost documentation. they have explained in detail.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Boost.Bind can't do it. You can't get a real function pointer from Bind. Nor from Function.

    The standard approach is this: callback mechanisms in C almost always allow you to pass a single pointer or pointer-sized integer along to the callback. You can put all data you need into this pointer: an object pointer, or even a full-blown Boost.Function object. You then specify a stub function as the callback, which does nothing but unpack the additional data and call the real callback.

    If the API does not provide this additional parameter, you've got a really big problem. Frankly, I don't think it's possible to solve this problem in a portable way. (The non-portable way, of course, is to generate machine code that looks like a C-style function on the fly and pass a pointer to that.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by CornedBee View Post
    If the API does not provide this additional parameter, you've got a really big problem. Frankly, I don't think it's possible to solve this problem in a portable way. (The non-portable way, of course, is to generate machine code that looks like a C-style function on the fly and pass a pointer to that.)
    It could also be accomplished by storing the object pointer in a global variable. If the usage is always non-reentrant, that's all that would be needed.

    Not saying it isn't ugly.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Yes. You could even use a thread-local storage area for the object pointer; that would at least solve the inevitable threading issues (at a certain performance cost). It would not, however, solve the problem of callbacks that are stored for later use instead of immediately used. (E.g. WndProc vs. qsort's comparison callback.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Sep 2007
    Location
    Houston, TX
    Posts
    5
    You should find some help here
    http://www.newty.de/fpt/callback.html#member

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by CornedBee View Post
    Yes. You could even use a thread-local storage area for the object pointer; that would at least solve the inevitable threading issues (at a certain performance cost). It would not, however, solve the problem of callbacks that are stored for later use instead of immediately used. (E.g. WndProc vs. qsort's comparison callback.)
    And of course, the TLS solution only works when the same thread is the calling thread later on. [I guess that might be what you mean in "WndProc" cases - qsort certainly is only calling in the same thread].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by garf13ld View Post
    You should find some help here
    http://www.newty.de/fpt/callback.html#member
    thanks, the wrapper it's what I'm using now. and it looks like it is going to stay that way. The other suggestions in this thread are beyond my level. but I'm still thankful for the interest!

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sorry to bring up an old point. Missed this one.
    Quote Originally Posted by pheres View Post
    I doesn't understand, why the language isn't improved to address the pointer conversion too, so that c-api can conveniently used in the world of OOP ...
    First of all, no amount of redefining the language will fix the fact that there just isn't enough information in a single pointer to convey the information necessary to call a member function within a class without the calling code understanding that it IS a "_thiscall".

    The Windows NT/2K/XP/Vista kernels are written in mainly in plain C (actually, I beleive the original Windows implementation was written in Pascal). Since the kernel isn't written in an object oriented language, it can't really "deal" with object oriented concepts in the callbacks etc. (there are OS's THAT ARE WRITTEN in for example C++, such as Chorus Streams and Symbian - and they often have "Objects" that take the place of a callback, so you pass in an object, and then whenever your "event" happens, a member function gets called).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by matsp View Post
    First of all, no amount of redefining the language will fix the fact that there just isn't enough information in a single pointer to convey the information necessary to call a member function within a class without the calling code understanding that it IS a "_thiscall".
    Maybe I'm to blue eyed, but I have this computer in front of my, and I know it is able to store all sort of things. And I want to let it store that object pointer for me.
    I just want to write:
    1. here it that c-function taking a callback. don't ask me, I've to use it if I want or not.
    2. here is my class, look at it's nice member xy I wrote all night long!
    3. Here is an object I create at run time. I know it's going to be created, belief me. If not, you can segfault and format may hard disk. It has a unique name and you even know the address, don't lie to me!
    4. now just store that information triple. I spend you 2GB of the most expensive ram and the biggest hard disc available at the local pc-store. So you should get it done!

    Why are that smart people that are able to design such complex languages and compilers and OS'es not willing to store and process such 3 simple 3-tuple?

  14. #14
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by pheres View Post
    Why are that smart people that are able to design such complex languages and compilers and OS'es not willing to store and process such 3 simple 3-tuple?
    It has NOTHING TO DO WITH C. The problem is that the API is not designed to accept this object pointer. You can't turn a dog into a cat.

    The object pointer is still there in C++, it is just hidden from view.

    So your complaint is baseless and ignorant.

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The computer is fully able to. But the designer of the API didn't consider it. It's a human error.

    (Actually, usually the designer of the API provided you with an additional void* pointer where you can pass whatever you want, so actually the designer did account for it. That makes it your error for not using this pointer.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  3. Can you check what is wrong with this code
    By Ron in forum C++ Programming
    Replies: 4
    Last Post: 08-01-2008, 10:59 PM
  4. Pointer to member
    By Billy in forum C++ Programming
    Replies: 3
    Last Post: 07-25-2002, 02:52 AM
  5. Function pointer to class member?
    By no-one in forum C++ Programming
    Replies: 2
    Last Post: 04-22-2002, 08:23 PM