当我尝试使用 dlopen() 将共享库加载到另一个共享库时遇到问题。我检查了所有关于如何正确使用 dlopen() 的教程。所以这里是简化的代码:
主共享库包含一个具有纯虚函数的类,子共享库(又名插件)必须实现该类。此外,它还有一些其他功能,这些功能是通过默认行为实现的。我创建了一个宏,它被添加到每个插件中,以便有一个符号来加载和创建类。
主共享库
插件.h:
Class A {
public:
virtual int func1() = 0;
virtual bool func2() const;
}
#define CREATE_CLASS(cls) extern "C" void *CreateClass(void) { return new cls; }
插件.cpp:
bool A::func2() const { return true; }
构建并链接 main.so
g++ -g -Wall -Woverloaded-virtual -Wno-parentheses -O2 -fPIC -c -o plugin.o plugin.cpp
g++ -g -Wall -Woverloaded-virtual -Wno-parentheses -O2 -fPIC -rdynamic -shared plugin.o -ldl -o main-plugin.so
子共享库只实现纯虚拟功能。另一个函数可以被覆盖,尽管它是可选的。
子共享库
插件-impl.cpp
Class B : public A {
public:
virtual int func1() { return 0; }
}
CREATE_CLASS(B)
这些是构建和链接子共享库的行。
构建和链接 sub.so
g++ -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses -fPIC -c -o subPlugin.o subPlugin.cpp
g++ -g -O3 -Wall -Werror=overloaded-virtual -Wno-parentheses -fPIC -shared subPlugin.o -o subPlugin.so
这是打开子共享库的行。我试过 LAZY,现在,现在 | GLOBAL 等等,没有任何影响。
dlopen() 在主共享库的某处调用:
handle = dlopen(file.c_str(), RTLD_LAZY);
其中大部分工作得很好。但是,当我尝试将子共享库加载到主共享库中时,dlopen 抱怨bool A::func2() const
. 该函数确实只存在于主共享库中,所以我想它无论如何都必须导出。请帮帮我!我很迷茫!
解决方案
因为我无法更改可执行文件,所以我必须通过将以下选项添加到 g++ 来链接主共享库和子共享库:
-L$(PLUGINDIR) -Wl,-R$(PLUGINDIR) -lmain-shared
使用此设置,无需设置LD_LIBRARY_PATH
.