【问题标题】:Getting function pointers from specific files从特定文件中获取函数指针
【发布时间】:2011-08-15 07:37:41
【问题描述】:

我有很多(可能数百个)不同的 c++ 文件。每个都包含 10 个函数,它们都接受一个 int 和一个 double 并返回一个 int。

因此,在这些文件之一中指向这些函数之一的指针将如下所示:

int (*foo)(int, double);

然后我有一个类,其中包含 10 个这样的函数指针。

是否可以让此类的构造函数获取这些 c++ 文件之一的文件名,将该文件的函数放入其指针中,以便以后能够使用这些函数?

最好它可以工作,这样即使来自不同文件的两个函数具有相同的名称,它仍然可以工作(这个想法是多个程序员可以将不同的文件提交到列表中,并且他们可以为他们的 10 个函数使用相同的名称),但如果这不可能,我可以想办法避免这种情况。

根据我的搜索,我似乎找不到任何可以让您在选择函数时区分文件的东西,即使我要将函数连接到一个文件中,仍然存在尝试指定哪个文件的问题10 个可供选择的函数(因为它们都有相同的参数)。

有没有办法做到这一点?有没有更好的解决方案我只是没有想到?

【问题讨论】:

  • 来自不同文件的函数可以放在文件的命名空间之一中。然后使用模板,您可以使用指定的命名空间创建多个对象。如果您添加示例,我会尝试更详细地解释它。

标签: c++ function-pointers


【解决方案1】:

有没有办法做到这一点?有没有比我更好的解决方案 只是没想到?

我认为您可以为它们使用不同的命名空间吗?我的意思是每组 10 个函数在它们自己的命名空间中;这样他们就不会再发生冲突了。

除此之外,您可以尝试一些 dlsym + dlopen 怪异(或他们的 win32 对应物)。不过这不是我会做的事情。

【讨论】:

    【解决方案2】:

    我相信您正在描述 dynamic linking library(在 Linux 领域中也称为 shared object)。

    【讨论】:

    • 您的代码听起来确实像是在乞求插件架构。将所有函数调用相同,将每个文件编译为自己的 .so/.dll,在运行时加载 一个 动态库并按名称从中获取函数指针。
    【解决方案3】:

    为了实现您的字面意思,您可以将每个 C++ 文件转换为动态库,并在库构造函数中使用 FILE 字符串作为键在某个全局映射中注册函数集或声明它们静态的,并确保每个文件都有一些静态变量,其初始化程序会触发函数在同一个全局映射中的注册。

    要实现相同的使用插件方法,您可以使用类似于我所做的here 的方式进行操作(只需下载 plugin.tgz,文章尚未准备好)。内容:

    • app.cc - 应用程序,加载所有插件的库
    • module.cc - 实现业务接口的插件类 module_ifc.h 和“可加载”接口 bootstrap_ifc.h
    • client.cc - 一个实现 bootstrap_ifc.h 并使用的插件 module.cc 中的方法在运行时解析

    每个具有相同功能集的 C++ 文件都有一个实现抽象业务接口(有用部分,所有功能)和引导接口(统一初始化部分,将由插件加载器使用)的类。每个这样的类都将被放入一个单独的共享库中,该库声明类实例构造函数和析构函数方法。

    一个在 Linux 上使用共享库的简单类:

    #include <dlfcn.h>
    
    class library {
      void* _handle;
    public:
      library(char const* path);
      ~library();
    
      template <typename F> F func(char const* name);
    };
    
    library::library(char const* path) {
      _handle = dlopen(path, RTLD_NOW);
      if (!_handle) throw std::runtime_error(dlerror());
      std::clog << "opened library " << path << ", handle=" << std::hex << _handle << std::dec << "\n";
    }
    
    library::~library() {
      if (_handle) dlclose(_handle);
      std::clog << "closed library, handle=" << std::hex << _handle << std::dec << "\n";
    }
    
    template <typename F> F library::func(char const* name) {
      dlerror();
      F func = reinterpret_cast<F>(dlsym(_handle, name));
      const char *dlsym_error = dlerror();
      if (dlsym_error) throw std::runtime_error(dlsym_error);
      std::clog << "loaded symbol " << name << ", ptr=" << std::hex << ((void*)func) << std::dec << "\n";
      return func;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-05
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多