我遇到的情况是我有一个依赖于库A的二进制文件,而该库又依赖于库B。

我已经针对库B构建了库A,但是库B:s的符号都没有泄漏出库A,所有内容都包含在cpp文件中。

现在我只想将二进制文件与库A链接,因为库A可以满足二进制文件中找到的所有符号。这可能吗?

在实际应用程序中,库B是网络协议的实现,我有很多二进制文件链接到中间库。而且我不希望二进制文件了解所使用的不同网络协议。

平台: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


解决此问题的最佳方法是什么?我是否必须将其创建为插件?

最好的祝福,
丹尼尔

最佳答案

如果要更改运行时使用的库,则不能直接链接它,而要使用“手动”加载。换句话说,呼叫dlopendlsym

这也可能意味着您需要在“ 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();

10-06 05:24