将两个库相互链接

时间:2018-09-10 07:42:39

标签: c++ c design-patterns shared-libraries

我在libA.so中使用了libB.so中的一个函数, 还有libB.so中使用的libA.so中的函数! 因此,毫无根据,我无法编译所有这些库。 如何编译这两个库? 我应该使用第三个图书馆并将依赖关系移至该图书馆吗? 我用qt和c ++

已更新: 在编译libA.so中获取错误找不到libB.so,在libB.so中获取错误找不到libA.so

4 个答案:

答案 0 :(得分:1)

对于将来的重用来说,这似乎有点问题,您可能希望将这些库之间的功能分开,或者创建第三个包含所有“工具”功能的LibA和{{ 1}}相互之间没有功能。

答案 1 :(得分:1)

大胖免责声明,仅在绝对必要时这样做。首选方法是重构项目结构,使其不包含依赖项循环。

生成共享库时,链接程序通常不需要了解其他共享库。可以在命令行上使用它们,但这是可选的。示例:

// libA.cpp
extern void funcB();
void funcA() {
    funcB();
}

编译并链接:

g++ -fPIC -c libA.cpp
g++ -shared -o libA.so libA.o

funcB应该居住在libB.so中,但我们没有告诉链接程序在哪里找到它。该符号只是在libA.so中未定义,将(希望)在加载时间 解析。

// libB.cpp
extern void funcA();
void funcB() {
   funcA();
}

现在使用显式使用libA.so进行编译和链接(忽略无限递归,这只是一个示例):

g++ -fPIC -c libB.cpp 
g++ -shared -o libB.so libB.o -L/where/libA/is -lA

现在,由可执行文件来加载libB.so,然后再加载libA.so,否则无法加载libA.so。这样做很容易(仅将可执行文件仅与libB.so链接,而不与libA.so链接),但有时会带来不便。因此,在构建libA.so之后,可以重新链接libB.so

g++ -shared -o libA.so libA.o -L /where/libB/is -lB

现在,一个程序可以将可执行文件链接到libA libB,而另一个程序将被自动提取。

答案 2 :(得分:0)

  

我在libA.so中有一个在libB.so中使用的函数,在libB.so中有一个在libA.so中使用的函数!

这是错误的设计library不能甚至间接依赖于它自己。这样的循环性是某些非常错误的症状,并且您误解了软件库是什么(它不仅仅是功能或目标文件的随机集合;它一定是某种“软件模块”并且与之相关)到modular programming并经常定义并完全实现 related abstract data types的集合。

因此同时丢掉libA.solibB.so 。并且制作一个单个 libAB.so ,其中包含您在libA.solibB.so共享库中放置的所有代码(不是真正的库)。

answer from n.m.提供了解决问题的技术方法,但从本质上讲,您的设计是错误的,并且您正在滥用库(并且无法调用libAlibB库,即使您将它们构建为ELF中的某个共享对象也是如此。

您还可以通过在变量或数据中添加callbacksclosuresfunction pointers间接添加一些间接设计(并提供设置这些回调或初始化的方法)在 runtime 处的闭包或函数指针)。由于您使用Qt,因此请考虑适当定义新的Qt signals and slots(它们基于某些回调机制)。

详细阅读Program Library HowTo和Drepper的How to Write Shared libraries论文。

答案 3 :(得分:-1)

最后我解决了。
如@ n.m。说我们不需要在编译时链接libA.so和libB.so,因此在构建它们时我删除了-lA-lB,但没有收到任何错误。在想要使用libA.so或libB.so的应用程序中,我将它们与-lA-lB链接在一起。这样就可以正常工作。