c++ - 链接c ++动态库不断失败
问题描述
我知道有很多关于它的帖子,但是我已经尝试过,但在链接我的库时仍然出现错误。
在我当前的目录中,我创建了一个动态库
/bin/library_test.so
源代码和包含文件与往常一样
./lib/ and ./src/
然后我试图编译一个简单的 main.cpp 并通过做链接库
g++ main.cpp -I/lib/ -L/bin/ -llibrary_test
但是我不断收到错误,例如“ExampleClass”没有在这个范围内声明,这意味着我没有链接库,对吧?因为这个类包含在我的库 cpp/头文件中。
我在链接中遗漏了什么,还是应该在我的 main.cpp 文件中添加一些包含命令?
解决方案
在您的命令和设置中检查有几个东西。另请查看C++ 编译阶段。您需要了解这一点才能完全理解您的问题。
查看您发表的评论,您遇到了 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
)。
推荐阅读
- javascript - 如果嵌套对象存在,则动态设置它们的属性。重新创建 _.extend
- c# - 查询长度未知时如何向查询添加参数
- pandas - 为条形图图例熊猫中的整数分配标签
- android - ARCore 原生错误 - Android error_policy_util.cc
- javascript - 以数字为前缀的函数调用
- javascript - 在 Windows 10 上的 Chrome 中以 HTML(聊天机器人图标)呈现 SVG 文件时出现问题
- docker - 我在哪里可以找到前一个构建阶段的复制工件?
- java - 使用处理实现 GLSL 着色器以进行聚光灯
- python - Reds_r 未被识别为有效的 RGBA 参数
- css - 动画在 Safari 和 IE 11 中无法处理页面重定向