c++ - 根据用户配置在运行时链接共享对象

标签 c++ linux c++11 shared-libraries

长话短说

我有一个我想在我的程序中使用的库,它有两个不同的版本。两个版本都提供相同的接口(interface),但用于编译它们的选项不同。

我现在想使用特定版本的库,但是,由于两个版本都适用于不同的任务,并且用户应该定义要执行的任务,我需要决定在运行时使用哪个库。

我知道我可以使用 dlopendlsym 根据用户的选择在运行时加载正确的库,但是界面非常大,加载我需要的一切进入不同的函数指针会很乏味......

问题

我有一个有两个不同版本的库。两个版本都提供相同的界面,但它们适用的任务不同。 这是文件树的样子:

lib
 \ - lib_task1
      \ - libsharedobj.so
 \ - lib_task2
      \ - libsharedobj.so

我想为用户提供选择在运行时执行哪个任务的可能性。因此,我还需要在运行时决定选择哪个库。 我的想法是编写一个包装器,它提供与库相同的接口(interface),在其中我将 dlopen 所需的库和 dlsym 将相应的符号转换为函数指针。然而,库接口(interface)非常大,按照描述包装它会非常乏味,再加上它是一个 C 接口(interface),所以它还包含许多我不希望在包装器外部看到的原始指针。

这是一个小例子

// library interface
typedef struct {
  // ...
} a_type;
void do_something(a_type* param);

// wrapper 
class LibWrapper {
private:
    void (*do_something)(a_type*);

    void* lib;
public:
    LibWrapper(const bool task_one) { // specified by the user
        if (task_one) {
            lib = dlopen("/usr/lib/lib_task1/libsharedobj.so", RTLD_NOW);
        } else {
            lib = dlopen("/usr/lib/lib_task2/libsharedobj.so", RTLD_NOW);
        }
        do_something = dlsym(lib, "do_something");
    }

    ~LibWrapper() {
        if (lib) {
            dlclose(lib);
        }
    }

    void do_something(std::unique_ptr<a_type> param) {
        do_something(param.get());
    }
};

问题

有没有更好的方法,或者我真的需要一个一个地加载每个符号吗?

操作系统:ubuntu 14.04。
兼容性:C++11

最佳答案

混淆 LD_PRELOAD 设置的一种方法可能是,当您的程序启动时,如果 LD_PRELOAD 设置不当,请确定您想要的设置,添加它,然后立即使用您自己的参数执行 execv 以重新启动! 我认为 LD_PRELOAD 在这里更有意义,如果它满足您的需要,因为更容易检测它是否按照您需要的方式设置。

关于c++ - 根据用户配置在运行时链接共享对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47508140/

相关文章:

c++ - 使用多态子类各自的方法

html - 如何在站点服务器中设置子域?

c++ - 对共享的 std::unordered_map 线程只写是否安全?

c++ - 如何使 -Wl,-y 可用于 C++ 代码

C++ 项目依赖问题 Visual Studio 2005

java - tomcat如何同时处理多个并发请求?

linux - 读取远程文件的 block 而不传输整个文件?

c++ - 隐式转换中的隐式参数

c++ - 使用可变参数模板在 C++ 中包装函数指针

c++ - 遍历 unordered_map cpp 的 unordered_map 中的元素