C++后端技术:静态链接与动态连接的编译解析

发表时间: 2024-03-07 15:32

静态连接

在编译时间完成,所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件,通常为“libxxx.a”的形式

add.h#ifndef _ADD_H_#define _ADD_H_int add(int a, int b);#endif
add.cpp#include "add.h"int add(int a, int b){    return a+b;}
sub.h#ifndef _SUB_H_#define _SUB_H_int sub(int a, int b);#endif 
sub.cpp#include "sub.h" int sub(int a,int b){  return a-b; }
main.cpp#include "add.h"#include "sub.h"#include "iostream"using namespace std;int main(){	cout<<"1+2="<<add(1,2)<<endl;	cout<<"1-2="<<sub(1,2)<<endl;    return 0;}

第一步

将add.cpp与sub.cpp编译成.0文件

g++ -c add.cppg++ -c sub.cpp

生成文件add.o sub.o,-c的编译选项,表示只执行到编译,输出目标文件。

第二步

由.o文件创建静态库(.a)文件

ar cr libmymath.a sub.o add.o

会生成libmymath.a文件

第三步

在程序中使用静态库

g++ -o main main.cpp -L. -lmymath

生成目标mian,并运行

动态链接

g++ -fPIC -o add.o -c add.cppg++ -fPIC -o sub.o -c sub.cppg++ -shared -o libmymath.so add.o sub.o或者一步解决g++ -fPIC -shared -o libmymath.so add.cpp sub.cpp

生成目标文件

g++ -o main main.cpp -L. -lmymath./mian

报错error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

因为找不到动态库文件libmymath.so,程序运行时,会在/usr/lib和/lib等目录下查找需要的动态库文件,找到就载入动态库

动态库搜索路径的先后顺序

1、编译目标代码时指定的动态库搜索路径

2、环境变量LD_LD_LIBRARY_PATH指定的动态库搜索路径

3、配置文件/etc/ld.so.conf中指定的动态库搜索路径

4、默认动态库搜索路径/lib

5、默认动态库搜索路径/usr/lib

解决方案

1、将文件libmymath.so复制到/usr/lib中

cp libmymath.so /usr/lib/

2、修改环境变量LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/usr/lib:$LD_LD_LIBRARY_PATHsudo ldconfig

动态库与静态库的重名问题

粉丝福利, 免费领取C/C++ 开发学习资料包、技术视频/项目代码,1000道大厂面试题,内容包括(C++基础,网络编程,数据库,中间件,后端开发,音视频开发,Qt开发,游戏开发,Linux内核等进阶学习资料和最佳学习路线)↓↓↓↓有需要的朋友可以进企鹅裙927239107领取哦~↓↓

有两个库文件libmymath.a和libmymath.so,同名时,会先到path目录下搜索libxxx.so,如果没有找到,则继续搜索libxxx.a(静态库)

静态库和动态库各自的缺点

动态库有利于进程间资源共享

某程序要调用动态库函数,操作系统会首先查看正在运行的程序,看在内存中是否有此函数的拷贝,有的话,就会共享哪一个拷贝。

静态链接库,每个程序需要调用都会拷贝到自己的代码段中

动态库升级简单

只要动态库给该程序的接口没变,只需要重新用新生成的动态库替换原来的就可以。如果是静态库,使用库的函数需要重新编译

动态库链接载入完全由程序员控制

可以明确的指明在什么情况下,载入哪个动态库。有一个很大的软件,每次运行的时候,根据操作需求去将一小部分载入内存

用静态库执行更快

在编译的时候,已经将库函数载到程序中去了,而动态库函数在运行时才被装在。所有在程序执行的时候,用静态库速度更快