我有一个场景,我有一个依赖于库 A 的二进制文件,而库 A 又依赖于库 B。
我已经针对库 B 构建了库 A,但是库 B:s 符号都没有从库 A 中泄漏,所有内容都包含在 cpp 文件中。
现在我只想将二进制文件链接到库 A,因为库 A 可以满足二进制文件中找到的所有符号。这可能吗?
在实际应用程序中,库 B 是网络协议(protocol)的实现,我有很多链接到中间库的二进制文件。而且我不希望二进制文件知道所使用的不同网络协议(protocol)。
平台:Linux/GCC
代码:
liba/liba.h:
#ifndef LIBA_H
#define LIBA_H
int getANumber();
#endif
liba/liba.cpp:
#include "liba.h"
#include "../libb/libb.h"
int getANumber(){ return getBNumber(); }
libb/libb.h:
#ifndef LIBB_H
#define LIBB_H
int getBNumber();
#endif
libb/libb.cpp:
#include "libb.h"
int getBNumber(){ return 42; }
main.cpp:
#include "liba/liba.h"
#include <iostream>
int main(int argc, char** argv) {
std::cout << getANumber() << std::endl;
return 0;
}
命令:
~/libb/ $ g++ -shared -o libb.so libb.cpp
~/liba/ $ g++ -shared -o liba.so liba.cpp -L../libb -lb
~/ $ g++ -o main main.cpp -Lliba -la # fails
~/ # These two work, but I don't want to specify libb here.
~/ $ g++ -o main main.cpp -Lliba -la -Wl,-rpath-link,libb
~/ $ LD_LIBRARY_PATH=libb g++ -o main main.cpp -Lliba -la
解决这个问题的最佳方法是什么?我必须将其创建为插件吗?
最诚挚的问候, 丹尼尔
最佳答案
如果您想更改在运行时使用的库,那么您不能直接链接它,而是使用“手动”加载。换句话说,调用dlopen
和 dlsym
这可能也意味着您在“liba”中需要稍微不同的架构,因为“libb”中的每个函数都变成了函数指针,所以沿着这些思路:
int (*getBNumber)() = NULL;
void initialize()
{
void *handle = dlopen("libb", RTLD_NOW);
getBNumber = (int (*)())dlsym(handle, "getBNumber");
}
int getANumber(){ return getBNumber(); }
您需要进行一些设置,以便在某个时刻调用初始化 - 或者在每个函数中都有一个 if (!initialized)initialize();
。
关于c++ - GCC/LD 仅针对直接依赖关系进行链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18076739/