开发者

Accessing C++ Functions From Text storage

I'm wondering if anyone knows how to accomplish the following:

Let's say I have a bunch of data stored in SQL, lets say o开发者_高级运维ne of the fields could be called funcName, function name would contain data similar to "myFunction" What I'm wondering is, is there a way I can than in turn extract the function name and actually call that function?

There's a few ways I can think of to accomplish this, one is changing funcName to funcId and linking up with an array or similar, but I'm looking for something a bit more dynamic that would allow me to add the data on fly without having to update the actual source code every time I add a call to a new function assuming of course that the function already exists and is accessible via scope location we call it from.

Any help would be greatly appreciated.


Use a macro to define new functions that register themselves automatically.

// callable_function.h
class CallableFunction {
 public:
  virtual void operator()() = 0;
};

class CallableFunctionRegistry {
 public:
  static CallableFunction *Register(const string &func_name,
                                    CallableFunction *func_impl) {
    Instance()->registered_functions_.insert(make_pair(func_name, func_impl));
  }

  static void Run(const string &func_name) {
    (*Instance()->registered_functions_[func_name])();
  }

 private:
  static CallableFunctionRegistry *Instance() {
    static CallableFunctionRegistry *instance = new CallablefunctionRegistry;
    return instance;
  }

  CallableFunctionRegistry() {}
  map<string, CallableFunction*> registered_functions_;
};

#define REGISTER_CALLABLE_FUNCTION(FuncName) \
  class FuncName : public CallableFunction { \
   public: \
    virtual void operator()(); \
  }; \
  CallableFunction *impl_ ##FuncName = \
    CallableFunctionRegistry::Register(#FuncName, new FuncName); \
  void FuncName::operator()()

And use it like this:

//other_file.cc
REGISTER_CALLABLE_FUNCTION(DoStuff) {
  // do stuff here.
}

And this:

//yet_another_file.cc
CallableFunctionRegistry::Run("DoStuff");

You could do it with function ptrs instead of CallableFunction object, but my syntax on that is hazy. Either way, add error checking for duplicate registrations and lookup not found.


Setup a mapping of names to function pointers or functors at program startup, then call by name via map lookup. Can also use dynamic libraries for extensions.

In the compiler/interpreter world it's called a symbol table, which usually also holds type (classes/structs), data declarations (variables), and function descriptors (argument and return types, etc.) It can also be nested according to the scope.


You can use the text you recevied from SQL and call GetProcAddress()

this will give you a function pointer you can call (assuming you are using Windows).

For Linux, take a look at dlsym


Approach #1 (most complicated):
Develop plugin system consisting of several dynamically linked libraries (*.dll on win, *.so on linux), with a few public functions that will tell your application which this plugin supports, function names, and pointers. Scan for plugins on startup, build function list that will map function names to their pointers.

Expect problems with variable number of parameters.

Approach #2 (brute force): Store all functions that you should be able to call within one dynamically linked library. When function name is extracted from database, get function pointer using GetProcAddress (win32) or dlsym(?) on linux.

Expect problems with variable number of parameters. Not the fastest, and not a smartest way.

Approach #3 (most flexible): Embed lua or python interpreter in your app.
This way you'll be able to store entire functions within database and should not have problems calling one of those. You'll still have to declare list of function you'll want to be accessable.

This won't be fool/hack proof, though, it will be possible to screw up entire app from within database, if you aren't careful enough.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜