• linux下g++链接动态库和静态库


    头文件的作用:

    include的作用就是复制内容到当前文件

    井号开头的就是预处理指令,由预处理器处理,预处理阶段不关心代码,只处理预处理指令。

    头文件主要 一是为了解决代码都写在一个文件太大了,二是把变量,结构体,函数声明这些固定的放在一起

    函数只要声明了,第二个阶段(编译阶段)语法检查就能通过,如果没定义实现,则第四个阶段链接时会报错link失败

    c++ 编译过程:

    1阶段,预处理阶段, 处理代码中的预处理指令,比如复制include到当前文件

    2阶段,编译阶段 6步: 扫描(词法分析)、语法分析、语义分析、源代码优化、代码生成、目标代码优化

    3阶段,汇编,把正确的汇编代码汇编位二进制代码

    4阶段,链接,这时候才会找头文件中声明的函数的定义,如果没有函数具体实现,就会报错

    链接作用:

    链接主要是把多个目标文件(.o文件) 放在一集合,解决每个目标之前引用的外部定义的变量、函数等地址引用问题

    首先会合并目标文件,这里可以理解为代码合并,然后函数调用的地方需要修改指向具体的函数位置,也就是重定位的原因。

    动态库

    动态库一般编译都会有-fPIC选项,也就是位置无关代码,代码的地址都是相对位置,加载到程序内存中任何位置都能正确执行。

    因为同一个动态库可能被不同的进程加载,加载位置肯定不一样。

    动态库在每个阶段的作用,来自AI

    动态库(.so文件)在程序运行阶段的作用是允许程序按需加载和卸载库文件,从而提高程序的灵活性和效率。
    在编译阶段,程序只需要连接动态库的符号信息,而不需要动态库的实际代码,因此生成的可执行文件体积通常比静态链接库更小。在运行阶段,程序会通过动态链接器将程序中引用的动态库加载到内存中,并将其映射到程序地址空间中的适当位置,然后程序就可以使用动态库中的函数和变量了。
    当程序不再需要库文件时,动态链接器会自动卸载它们,从而释放内存空间。此外,由于多个程序可以共享同一个动态库实例,因此动态库可以减少系统资源的消耗,并提高程序的运行效率。
    
    • 1
    • 2
    • 3

    动态库的用法

    g++ main.o -L 动态库的路径 -I 头文件路径 -l动态库名字(名字不需要前缀lib和后缀.so) // 可以链接多个库和头文件目录

    静态库:

    静态库可以为通过ar程序将多个目标文件.o 打包成一个文件,没做什么改动。

    链接时,主程序和静态库(多个目标文件一起链接)

    静态库的用法:

    g++ main.o -L 动态库的路径 -I 头文件路径 -l动态库名字(名字不需要前缀lib和后缀.so) -static // 可以链接多个库和头文件目录

    之所以加-stacic, 是因为链接命令都一样,都是-L, -I, -l, 所以gcc默认使用动态库链接,连接不上再尝试用静态库链接

    由于静态库是目标文件的合体,所以可以当作一个目标文件直接写名字进行链接: gcc main.c -I include lib/libTest.a -o app

    还有一个就是静态库的-fPIC选项, 当一个动态库依赖这个静态库时,由于动态库肯定是位置无关的,此时静态库被链接进去,也应该是位置无关的
    所以被依赖的静态库也要用-fPIC选项编译,通常也个选项是关闭的。

    如果静态库没有-fPIC,编译动态库链接会提示一堆重定位错误 reloaction 字样的信息

    如何查看是不是位置无关代码:

    动态库 readelf -d xxx.so |grp REL 存在REL就是,一般都是

    静态库 readelf --relocs xxx.a |grep GOT ,存在就时位置无关的。

    总个节:

    头文件就是代码, 只有编译的预处理阶段有用,运行时就没用了

    静态库只在编译时有用

    动态库运行时有用。

    编译阶段:

    自己写的动态库使用时除了gcc -L指定路径, 还可以放到环境变量路径下比如/bin, 但需要执行一次ldconfig更新动态库的缓存信息。

    也可以临时设定LIBRARY_PATH: export LIBRARY_PATH=${LIBRARY_PATH}:./lib/xxx.so

    运行阶段:

    除了把动态库放入环境变量设置的路径下,比如/bin 还可以设置export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:./lib/xxx.so

  • 相关阅读:
    公众号添加菜单总是提示请输入http://或https://开头的公众号相关链接
    Leetcode.4 寻找两个正序数组的中位数
    【Golang】程序如何优雅的退出?
    linux shell程序设计
    Intel RealSense D435i与IMU标定用于vins-fusion
    【光学】基于matlab模拟双孔干涉附matlab代码
    cookie和session区别
    【【RAM的verilog 代码 + testbench】】
    计算几何学知识点及C++代码代码实现汇总
    AD教程 (八)器件的复制和对齐
  • 原文地址:https://blog.csdn.net/weixin_44713496/article/details/132769186