长话短说
我有一个我想在我的程序中使用的库,它有两个不同的版本。两个版本都提供相同的接口(interface),但用于编译它们的选项不同。
我现在想使用特定版本的库,但是,由于两个版本都适用于不同的任务,并且用户应该定义要执行的任务,我需要决定在运行时使用哪个库。
我知道我可以使用 dlopen
和 dlsym
根据用户的选择在运行时加载正确的库,但是界面非常大,加载我需要的一切进入不同的函数指针会很乏味......
问题
我有一个有两个不同版本的库。两个版本都提供相同的界面,但它们适用的任务不同。 这是文件树的样子:
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/