动态库和静态库那些事


前言

经常使用到arm架构下静态库(.a)和动态库(.so),在使用过程中踩到不少坑,以此写下经鄙人验之谈,和需要了解和 学习的人一起互相学习。持续跟进追加,希望有一些我没有遇到的,欢迎补充。
(该行文内容使用在Makefile中,针对CMake部分后陆续更新)

静态库使用中的一些坑

  • 链接顺序问题
    • 第一种方式使用Xlinker解决,例如
      LIBS += foot.a LIBS += bar.a ${LD} 其他选项等略 -Xlinker "-(" $(LIBS) -Xlinker "-)"
    • 外一种方法为当静态库调用比较少时, 可以使用foot.a bar.a foot.a方式,即交换位置方式, 该方式不推荐,可以当做测试使用。
      LIBS += foot.a LIBS += bar.a LIBS += foot.a
      `

动态库使用中的坑和注意事项,规避等

  • c++调用c
    如果c中的接口(一般为h文件)没有添加如下
#ifndef __cplusplus
extern "C" {
#endif

void footfunc(const struct *IN, struct *OUT);
#ifndef __cplusplus
}
#endif

会导致链接错误,解决方式一种是接口中增加上面预编译代码段,如果对方没有提供源码,需要在调用方使用 如上代码包裹。

  • c文件名重命名cpp后缀
    有时候使用第三方的库和demo(c实现),但需要在demo中增加c++的接口库实现,比如libjson库,librtsp等, 将c文件重命名cpp文件,出现一系列的问题(c++语法严谨,可能会修改一些不严谨才能通过编译)。另外一个问题就是c中接口(通常为.h文件)增加如下的预编译段需要删除,只保留接口。
    项目: HI3519A venc RTSP推流
extern "C" {
#endif

void footfunc(const struct *IN, struct *OUT);
#ifndef __cplusplus
}
#endif
  • 一些低级错误导致
    比如有时候批量修改某些变量等,部分没有修改对,导致编译错误。

  • 源文件编译动态库增加-fPIC

@$(CPP) $(CPPOPTS) -fPIC $(DEFINES)

项目中的动态库静态库常用基本问题

  • 运行可执行文件报如下error cannot open shared object file: No such file or directory,解决方案是在运行的当前shell中增加动态库的路径(改路径一般为用户自定义的位置,非系统路径)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${需要链接的动态库绝对路径}
  • 当不清楚可执行文件调用了哪些库,可以使用ldd 可执行文件方式查看使用了哪些.so(动态库),该方式也可以看出没有链接到哪些动态库,如下可以看出来一些库是没有被链接,可通过系统搜索对应的动态库 find . -name librealsense2.so.2.49,然后使用1)中的方式装载。
ldd 你的可执行文件
linux-vdso.so.1 (0x0000007f8c558000)
	libMvCameraControl.so => /opt/MVS/lib/aarch64/libMvCameraControl.so (0x0000007f8c144000)
	librealsense2.so.2.49 => not found
	libMVbotdolly.so => not found
	libBaseAlgSDK.so => not found
	libmaxvision_algorithm_sdk_aarch64.so => not found
	libmax_thread.so => not found
	libmem_manager.so => not found
	librtspserver.so => not found
	libv4l_cap.so => not found
	libjetsonmedia.so => not found
	libopencv_core.so.4.5 => not found
	libopencv_imgcodecs.so.4.5 => not found
	libopencv_imgproc.so.4.5 => not found
	libopencv_videoio.so.4.5 => not found
	libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007f8c0f5000)
	libz.so.1 => /lib/aarch64-linux-gnu/libz.so.1 (0x0000007f8c0c8000)
	libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007f8bf34000)
	libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f8be7b000)
	libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007f8be57000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f8bcfe000)
	/lib/ld-linux-aarch64.so.1 (0x0000007f8c52c000)
	libGCBase_gcc48_v3_0.so => /opt/MVS/lib/aarch64/libGCBase_gcc48_v3_0.so (0x0000007f8bcd5000)
	libGenApi_gcc48_v3_0.so => /opt/MVS/lib/aarch64/libGenApi_gcc48_v3_0.so (0x0000007f8b835000)
	libXmlParser_gcc48_v3_0.so => /opt/MVS/lib/aarch64/libXmlParser_gcc48_v3_0.so (0x0000007f8b6da000)
	libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007f8b6c5000)
	libMathParser_gcc48_v3_0.so => /opt/MVS/lib/aarch64/libMathParser_gcc48_v3_0.so (0x0000007f8b6ab000)
	libLog_gcc48_v3_0.so => /opt/MVS/lib/aarch64/libLog_gcc48_v3_0.so (0x0000007f8b692000)
	libNodeMapData_gcc48_v3_0.so => /opt/MVS/lib/aarch64/libNodeMapData_gcc48_v3_0.so (0x0000007f8b668000)

  • 一些压缩包打包经过win系统,软连接会失效,压缩包尽量在linux下同下解压缩,不然只能一个个采用ln -s的方式做头疼的事情了。
  • 做文件系统等,如果静态库比较多,软连接也比较多, 尽量做成压缩包方式,脚本中尽量不要做ln -s的事情。
  • 关于使用动态库还是静态库, 如果是测试可执行,简单操作无需过多安装,使用静态库方式, 否则使用动态库。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值