链接C ++动态库不断失败

时间:2018-10-09 15:39:06

标签: c++ dll

我知道有很多关于它的文章,但是我已经尝试过了,但是在链接我的图书馆时仍然出现错误。

在当前目录中,我已在

创建了一个动态库。
/bin/library_test.so

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

./lib/ and ./src/

然后我尝试编译一个简单的main.cpp并通过

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

但是在此范围内,我一直在收到诸如“ ExampleClass”之类的错误,这意味着我尚未链接库,对吗?由于此类包含在我的库cpp / header文件中。

我是否在链接中缺少某些内容,还是应该在main.cpp文件中添加一些包含命令?

1 个答案:

答案 0 :(得分:1)

要检查命令和设置中有几项内容。另外,请检查C++ compilation phases。您需要了解这一点才能完全理解您的问题。

在评论中,您遇到了3个主要问题:

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

编译

在链接二进制文件之前,您收到的错误处于编译阶段。可能由于以下原因而产生此错误:

  • 您忘记了定义#include的标头的ExampleClass
  • 您没有告诉编译器搜索头的正确路径。在您的命令中,您告诉编译器在/lib(从文件系统根目录开始的目录)中搜索标头,而我确定您要在相对于当前工作目录的目录中搜索标头目录,表示-Ilib -Isrc

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

链接

一旦纠正了编译阶段,您可能会遇到链接问题,因为您的库未遵循linux中用于共享库的命名约定。库LIBRARYNAME的文件名应为libLIBRARYNAME.so

在某些情况下,您可能有多个版本的库,因此可以在so扩展名后添加带有semantic versioning约定的版本(例如,对于libLIBRARYVERSION.so.2.1库的版本2.1)。

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

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

运行时链接

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

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

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