0

我有一个场景,我有一个依赖于库 A 的二进制文件,而库 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; }

主.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

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

最好的问候,丹尼尔

4

1 回答 1

0

如果要更改在运行时使用的库,则不能直接链接它,而是使用“手动”加载。换句话说,调用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();在每个函数中都有一个。

于 2013-08-06T12:00:28.423 回答