【问题标题】:Accessing C++ Functions From Text storage从文本存储访问 C++ 函数
【发布时间】:2011-02-01 20:47:55
【问题描述】:

我想知道是否有人知道如何完成以下操作:

假设我有一堆数据存储在 SQL 中,假设其中一个字段可以称为 funcName,函数名称将包含类似于“myFunction”的数据我想知道的是,有没有办法比反过来提取函数名并实际调用该函数?

我可以想到几种方法来实现这一点,一种是将 funcName 更改为 funcId 并与数组或类似的链接,但我正在寻找更动态的东西,可以让我添加数据每次我添加对新函数的调用时都不必更新实际源代码,当然假设该函数已经存在并且可以通过我们调用它的范围位置进行访问。

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ sql function


    【解决方案1】:

    使用宏定义自动注册的新函数。

    // 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()()
    

    并像这样使用它:

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

    还有这个:

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

    您可以使用函数 ptrs 而不是 CallableFunction 对象来做到这一点,但我的语法是模糊的。无论哪种方式,为重复注册和未找到查找添加错误检查。

    【讨论】:

    • 哇,虽然我可能没有完全使用此代码,但它确实将我引向了另一条途径,我稍后将尝试实现我的目标。非常感谢您的回复和信息=)。
    • 祝你好运,很高兴我能帮上忙。
    【解决方案2】:

    在程序启动时设置名称到函数指针或函子的映射,然后通过映射查找按名称调用。也可以使用动态库进行扩展。

    在编译器/解释器世界中,它被称为symbol table,它通常还包含类型(类/结构)、数据声明(变量)和函数描述符(参数和返回类型等)。它也可以嵌套根据范围。

    【讨论】:

      【解决方案3】:

      方法 #1(最复杂):
      开发由几个动态链接库组成的插件系统(win 上的 *.dll,linux 上的 *.so),以及一些公共函数,这些函数将告诉您的应用程序该插件支持哪些功能、函数名和指针。在启动时扫描插件,构建函数列表,将函数名称映射到它们的指针。

      预计参数数量可变时会出现问题。

      方法#2(蛮力): 将您应该能够调用的所有函数存储在一个动态链接库中。 从数据库中提取函数名时,在 linux 上使用 GetProcAddress (win32) 或 dlsym(?) 获取函数指针。

      预计参数数量可变的问题。不是最快的,也不是最聪明的方法。

      方法 #3(最灵活): 在您的应用程序中嵌入 lua 或 python 解释器。
      这样,您将能够将整个函数存储在数据库中,并且调用其中一个函数应该不会有问题。您仍然需要声明您希望可访问的功能列表。

      不过,这不是傻瓜/黑客证明,如果你不够小心,可能会从数据库中搞砸整个应用程序。

      【讨论】:

      • 很好的答复,不幸的是,建议的方法需要对整个项目本身进行过多的大修,而我正在处理的是项目的一小部分,不能证明如此大的大修是合理的基本代码。感谢您提供的信息 =)。
      【解决方案4】:

      您可以使用从 SQL 中收到的文本并致电GetProcAddress()

      这将为您提供一个可以调用的函数指针(假设您使用的是 Windows)。

      对于 Linux,请查看dlsym

      【讨论】:

      • 如果我错了,请纠正我,但似乎 GetProcAddress() 指的是 DLL 中的导出函数/变量,我当前的程序没有将任何内容导出到 DLL。
      • @Undawned 然后你必须制作导出所有你想使用的函数的dll。
      • 您也可以从 .EXE 导出函数,无需 DLL。
      • @Ben:GetProcAddress 不支持;文档只说 DLL。
      • 可能起作用。今天。这就是为什么我说它不支持,并指向文档。而一旦病毒滥用它,无证路径被关闭。
      猜你喜欢
      • 1970-01-01
      • 2019-12-20
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      • 1970-01-01
      • 2015-12-01
      • 1970-01-01
      • 2019-06-15
      相关资源
      最近更新 更多