【发布时间】:2017-11-27 09:57:37
【问题描述】:
TL;DR
我有一个我想在我的程序中使用的库,它有两个不同的版本。两个版本都提供相同的接口,但用于编译它们的选项不同。
我现在想使用特定版本的库,但是,因为两个版本都适用于不同的任务,并且用户应该定义要执行的任务,所以我需要决定在运行时使用哪个库。
我知道我可以根据用户的选择使用dlopen 和dlsym 在运行时加载正确的库,但是接口非常大,将我需要的所有内容加载到不同的函数指针中会非常乏味.. .
问题
我有一个库,它有两个不同的版本。两个版本都提供相同的界面,但它们适用的任务不同。 这是文件树的样子:
lib
\ - lib_task1
\ - libsharedobj.so
\ - lib_task2
\ - libsharedobj.so
我想为用户提供选择在运行时执行哪个任务的可能性。因此,我还需要决定在运行时选择哪个库。
我的想法是编写一个包装器,它提供与库相同的接口,并在其中将 dlopen 所需的库和 dlsymthe 相应的符号放入函数指针中。但是,库接口非常大,按照描述包装它会很乏味,而且它是一个 C 接口,所以它还包含很多我不想在包装器之外看到的原始指针。
这是一个小例子
// 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
【问题讨论】:
-
主程序是否需要多次决定,和/或在启动之后,还是在启动期间知道需要哪个库实现,并且可以坚持到退出?
-
每次运行只加载一次,直到程序重新启动后才能更改决定。
-
您可以按照一些答案的建议更改库标题吗?
标签: c++ linux c++11 shared-libraries