无法在运行时加载动态共享库,包括 C++ 中的另一个共享库
Can't load dynamic shared library at runtime including another shared library in C++
我正在尝试实现一种类似于此处描述的设计:
http://www.linuxjournal.com/article/3687
我有一个编译成可执行二进制文件的核心项目。我还想使用 dlopen()
在运行时加载共享库。现在我面临的问题是,在核心项目和所有加载的库中应该知道一些 classes。我想我会把它们放在另一个共享库中,该库在编译时链接到所有这些库。一切似乎都可以正常编译,但是在加载共享库 ConnectionModule.so
dlopen returns 时没有句柄,dlerror 说 'undefined symbol: _ZTV17PipelineProcessor' 其中 PipelineProcessor
是在 class 中定义和实现的每次添加共享库都要编译的共享库。
有没有人知道我的实现有什么问题,或者这个设计注定要失败?
这里有一些代码:
运行时加载库
#include "../SharedHeaders/SharedInEveryLibrary.h"
// ...
map<string, maker_t*, less<string> > module_library;
// ...
void *hndl = dlopen(library_file_path, RTLD_NOW | RTLD_GLOBAL);
if (hndl == nullptr) {
Logger::error << "Could not load library " << library_file_name << ": " << dlerror() << endl;
exit(-1);
}
ConditionModule.h(应在运行时加载)
#pragma once
#include "../SharedHeaders/SharedInEveryLibrary.h"
class ConditionModule : public B {
public:
A* processRequest(X* data) override; // implemented at ConditionModule.cpp
};
extern "C" {
A *maker() {
return new ConditionModule;
}
class proxy {
public:
proxy() {
module_library["condition_module"] = maker;
}
};
proxy p;
}
...当然还有 SharedInEveryLibrary.h
的内容
class Z; // gets implemented later, I guess it's not important
struct X {
int something;
// ...
};
class A {
public:
virtual void setSomeData(X* v_some_data);
virtual A* process(Z* data) = 0;
protected:
X* some_data;
};
class B : public A {
public:
A* process(Z* data) override;
virtual A* processRequest(X* data) = 0;
};
typedef A* maker_t();
extern map<string, maker_t*, less<string> > module_library;
编辑 -----
忘了说我目前只用 Linux 作为编译目标进行开发。
这个设计没有任何问题。但是当你 dlopen() 共享库时,它的所有符号都需要解析。您的错误意味着您没有 .so 的路径,您的库依赖于 LD_LIBRARY_PATH。要检查它需要什么库,请使用
ldd <your library.so>
然后将这个库所在的目录添加到LD_LIBRARY_PATH。
我正在尝试实现一种类似于此处描述的设计: http://www.linuxjournal.com/article/3687
我有一个编译成可执行二进制文件的核心项目。我还想使用 dlopen()
在运行时加载共享库。现在我面临的问题是,在核心项目和所有加载的库中应该知道一些 classes。我想我会把它们放在另一个共享库中,该库在编译时链接到所有这些库。一切似乎都可以正常编译,但是在加载共享库 ConnectionModule.so
dlopen returns 时没有句柄,dlerror 说 'undefined symbol: _ZTV17PipelineProcessor' 其中 PipelineProcessor
是在 class 中定义和实现的每次添加共享库都要编译的共享库。
有没有人知道我的实现有什么问题,或者这个设计注定要失败?
这里有一些代码:
运行时加载库
#include "../SharedHeaders/SharedInEveryLibrary.h"
// ...
map<string, maker_t*, less<string> > module_library;
// ...
void *hndl = dlopen(library_file_path, RTLD_NOW | RTLD_GLOBAL);
if (hndl == nullptr) {
Logger::error << "Could not load library " << library_file_name << ": " << dlerror() << endl;
exit(-1);
}
ConditionModule.h(应在运行时加载)
#pragma once
#include "../SharedHeaders/SharedInEveryLibrary.h"
class ConditionModule : public B {
public:
A* processRequest(X* data) override; // implemented at ConditionModule.cpp
};
extern "C" {
A *maker() {
return new ConditionModule;
}
class proxy {
public:
proxy() {
module_library["condition_module"] = maker;
}
};
proxy p;
}
...当然还有 SharedInEveryLibrary.h
的内容class Z; // gets implemented later, I guess it's not important
struct X {
int something;
// ...
};
class A {
public:
virtual void setSomeData(X* v_some_data);
virtual A* process(Z* data) = 0;
protected:
X* some_data;
};
class B : public A {
public:
A* process(Z* data) override;
virtual A* processRequest(X* data) = 0;
};
typedef A* maker_t();
extern map<string, maker_t*, less<string> > module_library;
编辑 ----- 忘了说我目前只用 Linux 作为编译目标进行开发。
这个设计没有任何问题。但是当你 dlopen() 共享库时,它的所有符号都需要解析。您的错误意味着您没有 .so 的路径,您的库依赖于 LD_LIBRARY_PATH。要检查它需要什么库,请使用
ldd <your library.so>
然后将这个库所在的目录添加到LD_LIBRARY_PATH。