# Member function pointer calling [WORKING]

This topic is 3258 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Dear Thread reader, I had an idea about a class that will allow me to call member functions like they where normal functions. I'm not at my development pc right now so I can't really test this but I tough that maybe one of you guys knows if this might work. Here is a sample:
typedef int (*memfunct)(void* _this, int argument);

class member_function
{
public:
member_function(void* _class, memfunct funct)
{
m_class = _class;
m_funct = funct;
}

int call(int argument)
{
return m_funct(m_class, argument);
}

private:
void*    m_class;
memfunct m_funct;
};

class A
{
public:
int do(int argument)
{
std::cout << argument;
return argument+1;
}
}

int main()
{
A aclass;
member_function afunction(&aclass, (memfunct)A::do);

afunction.call(15);

return 0;
}


Now my question is, will this work or do I have to do some secret assembly magic? I have a general idea of how that will work. Just pop all arguments (including the this pointer) and then call the function address. But of course it would be nicer if this worked. I will check it out as soon as I get to my dev pc. Ow and I'm using linux so I would compile this with g++. Tjaalie, [Edited by - Tjaalie on August 19, 2009 8:55:02 AM]

##### Share on other sites

Sample usage:
struct Foo{    void Bar();};Foo object;boost::function<void()> function = boost::bind(&Foo::Bar(), &object);/*...*/function(); // calls object.Bar();

##### Share on other sites
No that won't work. If it does for testing, then it's just a lucky coincidence.

You can, however, still do that - safely and effectively - via boost::function and boost::bind:
A aclass;boost::function<int(int)> afunction = boost::bind(&A::foo, boost::ref(A));afunction(16);

(btw you can't call your function do, that's a keyword)

Edit: Ninja'd. BTW Sc4Freak when you bind, get rid of the () or it looks like you're trying to call the function.

##### Share on other sites
Quote:
 Original post by nullsquaredEdit: Ninja'd. BTW Sc4Freak when you bind, get rid of the () or it looks like you're trying to call the function.

Ah, yes. Nicely caught. [grin]

Corrected:
boost::function<void()> function = boost::bind(&Foo::Bar, &object);

##### Share on other sites
Thank you, I know of the template stuff but I tough it looked nice if that would work. Too bad, I actually found a compiler on this computer and tried some stuff. I was able to get the address of a normal function into a 64 bit integer, but I couldn't get a member functions address. Is this also impossible? I'm just messing around with some idea's it doesn't really have a function yet, but it will as soon as my scripting engine will be capable of calling c++ functions. I rather not use boost because I'm programming for my own fun and want to do everything from scratch, its really fun to reinvent the wheel from a experience point of view. But thanks for your quick responses, that's why I love these forums. So is it possible to get the address of the function into a integer (or void*) I know this is really bad practice.

edit:

this is what I got so far.

//worksunsigned long long functptr = (unsigned long long)&main;//gives error (renamed do to doit)unsigned long long functptr = (unsigned long long)&A::doit;

##### Share on other sites
That's because member function pointers work differently. See this link for an in-depth dissection of the implementation details of member function pointers.

##### Share on other sites
Quote:
 Original post by Tjaalieit will as soon as my scripting engine will be capable of calling c++ functions.

That's precisely why you want to use boost. Luabind, which is a C++ bindings library for Lua, makes extensive use of boost. This allows you to mix and match C/C++ functions/member-functions/functors and Lua functions very, very easily.

##### Share on other sites
Call me crazy but I got it to work. Here is the totally messy code that shouldn't be used for anything other than experiments like this. I'm not going to use this code because this is probably undefined behaviour that somehow works the way I want it to work.

#include <iostream>typedef int (*memfunct)(void* _this, int argument);class member_function{public:  member_function(void* _class, void** funct)  {    m_class = _class;    m_funct = (memfunct)*funct;  }  int call(int argument)  {    return m_funct(m_class, argument);  }private:  void*    m_class;  memfunct m_funct;};class A{public:  int doit(int argument)  {    std::cout << argument;    return argument+1;  }};int main(){  A aclass;  int (A::*funct)(int) = &A::doit;  member_function afunction(&aclass, (void**)&funct);    afunction.call(15);  return 0;}

It prints '15' when compiled using g++. Maybe someone dares to try this with visual studio, just to see if it works.

edit:
I tried the code with member variables in the class A. Everything seems to work just as expected. If I can find a way to cleanly convert the member function to a void** without the need of the extra variable I might be able to actually use this. Although maybe not the smartest thing to do but it seems to work.

##### Share on other sites
With VC 2005 your code outputs 1245027. It seems that you are making some unsafe assumptions about how a member function call happens.

It outputs 15 if you explicitly specify __stdcall as calling convention:

class A{public:  int __stdcall doit(int argument)  {    std::cout << argument;    return argument+1;  }};int main(){  A aclass;  int  (__stdcall A::*funct)(int) = &A::doit;  member_function afunction(&aclass, (void**)&funct);  afunction.call(15);  return 0;}

All in all, it looks like a very fragile hack.

##### Share on other sites
haha, funny.
I don't think I will be using this. The only way to make this work in a way that I think has some nice notation is with a marco from hell.

##### Share on other sites

This topic is 3258 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

This topic is now closed to further replies.

1. 1
2. 2
3. 3
Rutin
22
4. 4
JoeJ
16
5. 5

• 14
• 30
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631774
• Total Posts
3002295
×