首页 > 解决方案 > 链接c ++动态库不断失败

问题描述

我知道有很多关于它的帖子,但是我已经尝试过,但在链接我的库时仍然出现错误。

在我当前的目录中,我创建了一个动态库

/bin/library_test.so

源代码和包含文件与往常一样

./lib/ and ./src/

然后我试图编译一个简单的 main.cpp 并通过做链接库

 g++ main.cpp -I/lib/ -L/bin/ -llibrary_test

但是我不断收到错误,例如“ExampleClass”没有在这个范围内声明,这意味着我没有链接库,对吧?因为这个类包含在我的库 cpp/头文件中。

我在链接中遗漏了什么,还是应该在我的 main.cpp 文件中添加一些包含命令?

标签: c++dll

解决方案


在您的命令和设置中检查有几个东西。另请查看C++ 编译阶段。您需要了解这一点才能完全理解您的问题。

查看您发表的评论,您遇到了 3 个主要问题:

  1. 编译(预处理之后和组装和链接之前)
  2. 链接(仍然在编译器运行时)
  3. 运行时链接(在执行编译的二进制文件期间)

汇编

在链接二进制文件之前,您收到的错误处于编译阶段。可能会生成此错误,因为:

  • 您忘记了#include定义的标头ExampleClass

  • 您没有告诉编译器搜索标头的正确路径。在您的命令中,您告诉编译器在/lib(从文件系统的根目录开始的目录)中搜索标头,而我很确定您想在相对于当前工作目录的目录中搜索它们,即-Ilib -Isrc.

    顺便说一句,我强烈建议您将所有源文件放在一个src目录中,并将所有头文件放在一个include目录中,这通常在复杂的 C/C++ 项目中完成。

链接

更正编译阶段后,您可能会遇到链接问题,因为您的库没有遵循 linux 中用于共享对象的命名约定。库的文件名LIBRARYNAME应该是libLIBRARYNAME.so.

在某些情况下,您可能拥有多个版本的库,因此可以在扩展后添加具有语义版本控制约定的版本so(例如libLIBRARYVERSION.so.2.1,对于您的库的 2.1 版)。

要链接上述库,您必须使用该-lLIBRARYNAME选项。

为了在链接时通知您的编译器在哪里可以找到该库,您应该提供带有 的路径-L,但此选项仅通知编译器并且不会保存此类库在可执行文件中的位置。

运行时链接

在这种情况下,有两个主要场景(我会有点草率,但只是为了给你指出正确的方向。完整的解释可能需要更多的空间......和时间):

  • 您可以使用 对二进制文件中共享库的位置进行硬编码rpath,但如果您分发应用程序,最终用户必须在您通过 rpath 指定的同一路径中拥有该库,这就是我倾向于避免使用此解决方案的原因。
  • 现代 linux 系统能够搜索所需的共享对象(这就是存在命名约定的原因)。搜索在受信任的目录中执行,搜索路径通过ldconfig配置文件(或$LD_LIBRARY_PATH环境变量)配置。在搜索路径中安装新库时,应刷新运行时链接器的缓存(同样,这是通过ldconfig或通过重新启动完成的)。我强烈建议您阅读该链接,ldconfig因为它向您解释了如何配置新的搜索路径(就像/usr/local/lib您的情况一样)。

您可以通过命令检查二进制文件是否能够找到所有必需的共享对象ldd BINARY_NAME(在您的情况下ldd a.out)。


推荐阅读