我知道有很多关于它的帖子,但是我已经尝试过,但在链接我的库时仍然出现错误。
在我当前目录下,我创建了一个动态库在
/bin/library_test.so
源代码和包含文件和往常一样
./lib/ and ./src/
然后我尝试编译一个简单的 main.cpp 并通过执行链接库
g++ main.cpp -I/lib/ -L/bin/ -llibrary_test
但我不断收到类似“ExampleClass”未在此范围内声明的错误,这意味着我还没有链接库,对吗?由于此类包含在我的库 cpp/header 文件中。
我是不是在链接中遗漏了什么,或者我应该在我的 main.cpp 文件中添加一些 include 命令?
最佳答案
在您的命令和设置中有几个东西需要检查。另请查看 C++ compilation phases .您需要了解这一点才能完全理解您的问题。
查看您的评论,您有 3 个主要问题:
- 编译(预处理之后,组装和链接之前)
- 链接(仍在编译器运行时)
- 运行时链接(在执行已编译的二进制文件期间)
编译
您收到的错误是在链接二进制文件之前的编译阶段。产生此错误的原因可能是:
您忘记了定义
ExampleClass
的 header 的#include
您没有告诉编译器搜索 header 的正确路径。在你的命令中,你告诉编译器在
/lib
(一个从文件系统的根目录开始的目录)中搜索 header ,而我很确定你想在相对目录中搜索它们到您当前的工作目录,意思是-Ilib -Isrc
。顺便说一句,我强烈建议您将所有源文件放在
src
目录中,将所有 header 放在include
目录中,这通常是这样做的在复杂的 C/C++ 项目中。
链接
一旦您纠正了编译阶段,您可能会遇到链接问题,因为您的库不遵循 linux 中用于共享对象的命名约定。库 LIBRARYNAME
的文件名应为 libLIBRARYNAME.so
。
在某些情况下,您可能拥有多个版本的库,因此可以添加带有 semantic versioning 的版本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
)检查二进制文件是否能够找到所有必需的共享对象。
关于c++ - 链接c++动态库一直失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52724714/