user14416
user14416

Reputation: 3032

C++ runtime member function access by string name

I have two classes:

class MyClassInfo {
public:
  void AddMethod(std::string name, void* pointer); // I don't know what signature should be
}
class MyClass
{
public: 
  void SetField1(int f1);
  int GetFileld1();
private:
  int field1;
};

I need to be able to access the methods of MyClass by name (string) during runtime. I don't want to use any libraries (except boost) and/or compiler functionality (such as rtti) to do that.

I don't know which signature I should use in AddMethod method, because I don't know how to transmit the function pointer to the function. This function must be a universal function which allows to add any method. Maybe you know a better variant how to do that without MyClassInfo. Any help will be appreciated.

Upvotes: 4

Views: 2977

Answers (2)

Bart van Ingen Schenau
Bart van Ingen Schenau

Reputation: 15768

If all functions you want to pass through AddMethod have the same signature (possibly after binding some of the arguments), you can use this signature:

void AddMethod(std::string name, boost::function<int ()> func);

and use like this:

info.AddMethod("GetFileId1", std::bind1st(std::mem_fun(&MyClass::GetFileId1), &MyClassInstance);

If the functions have different signatures, you could store them using boost::function_base:

void AddMethod(std::string name, boost::function_base func);

and you use it like above. The challenge is now to find out exactly what type is stored in the boost::function object so you can use it.

Upvotes: 0

john
john

Reputation: 8027

That is not possible in directly C++. You will have to look at alternatives like creating a map of names to member function pointers. But even that would require consistent method signatures.

Something like

std::map<std::string, int (MyClass::*)(void*))

for instance. Your AddMethod signature would then look like this

void AddMethod(std::string name, int (MyClass::* pointer)(void*));

and you would call it like this

info.AddMethod("someMethod", &MyClass::someMethod);

Upvotes: 3

Related Questions