Linux中动静态库的创建与原理

[复制链接]
发表于 2025-10-9 22:03:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
        一、什么是库?

简朴来说库就是现成的,可以复用的代码,在我们的Linux体系中默认安装了C语言库,如许我们才气在Linux上运行C语言的代码

  二、静态库(.a)的创建

在当前self文件夹里,有我们本身实现的stdio.c,stdio.h,string.c,string.h文件
.h文件中生存了相应的方法名,.c文件里生存了方法的详细实现,假设我现在想让圈外人使用我实现的方法但是却不想让他知道方法怎样实现的,那么我们就可以通过创建静态库的方法,即让圈外人能使用我的实现的函数,而且还不能看到我们.c文件内里的详细实现

第一步,通过对.c文件编译,使其酿成.o文件

第二步,通过对两个.o文件链接打包形成静态库
  1. libmystdio.a:   lib前缀 + 库名(stdio) + (.a)后缀  
  2. ar -rc libmystdio.a my_stdio.o my_string.o
复制代码
可见,对两个.o文件乐成打包成静态库 
 


静态库的使用方法一

在Linux体系里,C语言的头文件是在体系里的,库也是在体系里的,因此我们想使用我们的静态库,也可以模拟尺度的C语言库,将我们本身的.h文件和静态库加到体系里,本质也是拷贝,windows下也一样

 查察usr/include/目次下全部my_文件,可以看到我们的两个头文件已经被乐成加载到体系里了

将我们的头文件加载到体系后,我们本身的静态库也以同样的方法加载到体系里

此时,假如第三方职员想使用我这个库中的函数,他创建了一个main.c文件,在VScode中我们也可以清晰看到,当前体系内里已经辨认出来了我们本身的头文件

第三方职员完备的main.c文件如下 
  1. #include<my_stdio.h>
  2. #include<my_string.h>
  3. #include<stdio.h>
  4. int main()
  5. {
  6.     const char *s = "abcdefg";
  7.     printf("%s: %d\n", s, my_strlen(s));
  8.     mFILE *fp = mfopen("./log.txt", "a");
  9.     if(fp == NULL) return 1;
  10.     mfwrite(s, my_strlen(s), fp);
  11.     mfwrite(s, my_strlen(s), fp);
  12.     mfwrite(s, my_strlen(s), fp);
  13.     mfclose(fp);
  14.     return 0;
  15. }
复制代码
 上面的代码看起来没有题目,按照寻常明确来说应该也能乐成运行,可真到了运行的时间,却发生了下面的报错

这是编译错误,我们可以肯定,我们本身的头文件和库显着已经安装到体系内里的,为什么还会发生编译错误?由于我们没有没有告诉gcc要链接谁人库,由于gcc是默认找到C尺度库的,我们纵然本身的库和C语言尺度库再像,也只不外是一个第三方库而已,以是假如我们想运行乐成上面的代码,就必要告诉gcc该链接哪一个库
  1. 解决方法: gcc main.c -l 库名
  2. 注意:库名是去掉前缀(lib)和后缀(.a) 剩下的部分
复制代码

 静态库的使用方法二

假如我们不想把头文件 和本身的静态库到场到本身材系里,该怎么使用呢?
现在我们已经把原来到场到体系的头文件和静态库删除

将头文件和静态库打包给第三方,此时第三方手上的文件:

运行main.c文件,发现头文件报错,由于我们此时体系内里已经没有了这两个.h文件

修改main.c文件内里的头文件:

再次运行,发现出现了与方法一同样的错误

由于gcc默认找的是尺度C语言库,那我们就告诉gcc找哪个库,但照旧编译报错,告诉我们没有这个库,这是为什么呢?由于gcc默认是去/lib64/路径下去找的,可我们的库的位置与main.c划一
  1. 解决方法:告诉gcc在哪个路径下找静态库
  2. gcc main.c -L. -l mystdio
  3. -L:哪个路径查找
  4. -l:查找的库名
复制代码

静态库的使用方法三

使用makefile主动构建项目
makefile文件如下:
  1. libmystdio.a:my_stdio.o my_string.o
  2.         @ar -rc $@ $^
  3.         @echo "build $^ to $@ ... done"
  4. %.o:%.c
  5.         @gcc -c $<
  6.         @echo "compling $< to $@ ... done"
  7. .PHONY:clean
  8. clean:
  9.         @rm -rf *.a *.o stdc*
  10.         @echo "clean ... done"
  11. .PHONY:output
  12. output:
  13.         @mkdir -p stdc/include
  14.         @mkdir -p stdc/lib
  15.         @cp -f *.h stdc/include
  16.         @cp -f *.a stdc/lib
  17.         @tar -czf stdc.tgz stdc
  18.         @echo "output stdc ... done"
复制代码
make,然后make output发布 

第三方得到了一个含有头文件与静态库的文件夹 

第三方怎样使用 
效仿法二使用静态库,可以看到,gcc告诉我们找不到头文件了

  1. 解决方法:
  2. gcc main.c -I stdc/include/ -L stdc/lib -l mystdio
  3. -I:去哪个路径找头文件
  4. -L:去哪个路径找静态库
  5. -l:找哪个静态库
复制代码
 至此,静态库的创建和使用完毕

三、动态库(.so)的创建

makefile文件如下:
  1. libmystdio.so:my_stdio.o my_string.o
  2.         gcc -o $@ $^ -shared
  3. %.o:%.c
  4.         gcc -fPIC -c $<
  5. .PHONY:clean
  6. clean:
  7.         @rm -rf *.so *.o stdc*
  8.         @echo "clean ... done"
  9. .PHONY:output
  10. output:
  11.         @mkdir -p stdc/include
  12.         @mkdir -p stdc/lib
  13.         @cp -f *.h stdc/include
  14.         @cp -f *.so stdc/lib
  15.         @tar -czf stdc.tgz stdc
  16.         @echo "output stdc ... done"
复制代码
动态库的使用方法一

与静态库划一,将头文件加载到体系里

与静态库划一,将动态库加载到体系里

第三方职员的main.c文件与静态库的使用方法逐划一,运行后发现找不到库

指定gcc找哪个库后,就能正常运行

动态库的使用方法二

把原来到场到体系的头文件和动态库删除
 

第三方手上动态库和头文件

main.c文件内里的.h已经更改

与静态库的使用方法二划一,得指定gcc在哪个路径下找库,找哪个库

动态库的使用方法三

第三方手上已经有stdc文件夹,内里有头文件和动态库 

 指定路径找头文件,指定路径找动态库,找指定库名的动态库

此时可以看到,这种情况与静态库并不一样,固然也能生存可实验文件,但是却无法运行,体系也告诉我们找不到动态库,这是为什么呢?
缘故起因:由于动态库与静态库差别,对于动态库,OS是必要加载的,从那里加载:/lib64/下加载,
你-L选项只是告诉gcc,并没有告诉OS,全部就会报错 
办理方法:
1.像方法逐一样,将动态库拷贝到/lib64/目次下
2.体系路径中,创建软链接
3.设置情况变量,但是如许每一次开机都会重置

4.进入bashrc(在根目次下),修改export,这里就不再演示


回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表