【c语言】gcc编译动态库静态库和使用说明

时间:2025-04-05 07:55:35

目录

(1)linux和win下库后缀名

(2)动态库的封装和使用

示例1

示例2

(3)gcc编译程序时找库说明

(4)静态库的封装和使用

示例1

示例2

(5)动态库和静态库的使用区别 

(6)编译时指定动态库或者静态库编译


(1)linux和win下库后缀名

在WIN上封装为.dll(动),.lib(静)。

在LINUX上封装为.so(动),.a(静)

(2)动态库的封装和使用

示例1

源代码文件:、

1.生成动态库(将生成动态库)

  1. #生成
  2. #参数 -fPIC 表示生成与位置无关代码,执行完毕后生成一系列的 .o 文件
  3. gcc -o -c -fPIC
  4. #生成(windows动态库)
  5. gcc -shared -o
  6. #生成(linux动态库)
  7. gcc -shared -o

2.编译可执行文件(在只有和func动态库的情况下编译)

  1. # 假设func动态库在当前目录下
  2. # 生成可执行文件main
  3. gcc -o main -L . -l func

3.运行可执行文件

  1. 先将动态库放到可执行文件的同级目录下
  2. 或者执行如下命令(linux环境时)
  3. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库所在目录路径
  4. 然后执行可执行文件
  5. ./main

示例2

1.生成"与位置无关"的目标文件

gcc -fPIC    -c -I ../include

参数 -fPIC 表示生成与位置无关代码,执行完毕后生成一系列的 .o 文件

2.制作动态库

  1. # linux
  2. gcc -shared -o
  3. # windows
  4. gcc -shared -o

动态库使用

示例

  1. [root@CentOS2 xxx]# ls
  2. temp
  3. [root@CentOS2 xxx]# gcc -L./ -ladd -I./ -o test_so
  4. [root@CentOS2 xxx]# ls
  5. temp test_so
  6. [root@CentOS2 xxx]# pwd
  7. /root/xxx
  8. [root@CentOS2 xxx]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/xxx
  9. [root@CentOS2 xxx]# ./test_so
  10. 1+2=3
  11. [root@CentOS2 xxx]#

(3)gcc编译程序时找库说明

我们⽤gcc编译程序时,常常会⽤到“-I”(⼤写i),“-L”(⼤写l),“-l”(⼩写l)等参数,下面做个记录:例:

gcc -o hello    -I /home/hello/include -L /home/hello/lib -l world

这条命令运⾏后,会在当前⽂件夹下产⽣⼀个hello⽂件,这个⽂件就是可执⾏⽂件。在当前⽂件执⾏命令./hello,即可运⾏该⽂件。

  • -I /home/hello/include,表示将/home/hello/include⽬录作为第⼀个寻找源代码中引⼊的头⽂件的⽬录,寻找的顺序是:/home/hello/include –> /usr/include –> /usr/local/include, 也就是指定优先查找的⽬录,找不到的话查找默认⽬录。如果没有-I相关的指定,那么就是省略头⽂件位置默认为当前⽂件夹。
  • -L /home/hello/lib,表示将/home/hello/lib⽬录作为第⼀个寻找库⽂件的⽬录, 寻找的顺序 是:/home/hello/lib –> /lib –> /usr/lib –> /usr/local/lib,同上,也是指定优先查找的⽬ 录,如果省略就是指当前⽂件夹优先。"-L . "表示在当前⽬录找。
  • -l word, 表示寻找具体的动态链接库⽂件或者,如果 在最后 再加上编译选项 static,表示寻找静态链接库⽂件,也就是或者。

(4)静态库的封装和使用

示例1

源代码文件:、

1.生成静态库(将生成静态库)

  1. #生成
  2. gcc -o -c
  3. #生成 (linux静态库)
  4. ar -crv
  5. #生成 (windows静态库
  6. ar -crv

2.编译可执行文件(在只有和func静态库的情况下编译)

  1. # 假设func静态库在当前目录下,且没有func动态库
  2. # 生成可执行文件main
  3. gcc -o main -L . -l func

3.运行可执行文件

  1. # 只要可执行文件时链接静态库生成的
  2. # 不管当前目录有没有静态库,直接运行可执行文件即可
  3. ./main

示例2

1.生成.o文件

这里会生成、、文件

gcc    -c -I ../include

2.将.o文件打包得到静态库文件

  1. # 就是一个打包.o文件的过程,以为例
  2. # linux
  3. ar rcs
  4. # windows
  5. ar rcs

说明:

  • ar 工具不包含在gcc中
  • r --> 将文件插入静态库中
  • c --> 创建静态库,不管库是否存在
  • s --> 写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。

静态库使用

gcc + 源文件 + -L 静态库路径 + -l静态库名 + -I头文件目录 + -o 可执行文件名

  1. #gcc + 源文件 + -L 静态库路径 + -l静态库名 + -I头文件目录 + -o 可执行文件名
  2. gcc -L./ -lmytest -I./ -o test
  3. 或者
  4. #gcc + 源文件 + -I头文件目录 + + -o 可执行文件名
  5. gcc -I./ -o test

(5)动态库和静态库的使用区别 

静态库是必须要链接到执⾏⽂件中去的,⽽动态库是不需要链接到最后的执⾏⽂件中的,也就是说,对于最后的执⾏⽂件⽽⾔,如果是链接静态库生成的可执行文件,在运行可执行文件时,你是否删除静态库⽆所谓。但是,如果是链接动态库生成的可执行文件,⼀旦你删除了动态库,最后的可执⾏⽂件就玩不转了。

用动态库编译特点

1,库的代码不会编译进程序⾥⾯,所以动态库编译的程序⽐较⼩。

2,由动态库编译的程序依赖于系统的环境变量有没有此库⽂件,⽆则运⾏不了。

用静态库编译特点

 1,库的代码会编译进程序⾥⾯,所以静态库编译的程序⽐较⼤

 2,由静态库编译的程序不⽤依赖于系统的环境变量,所以环境变量有没有这个库⽂件,也 可以运⾏。

静态库使用优缺点

  • 优点:库被打包到可执行程序中,直接发布可执行程序即可使用
  • 缺点:静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。如果静态函数库改变了,那么你的程序必须重新编译。
  • 使用场合:在核心程序上使用,保证速度,可忽视空间。主流应用于80、90年代,现在很少用。

动态库使用优缺点

  • 机制:共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。
  • 优点:节省内存(共享)、易于更新(动态链接):停止运行程序 → 使用新库覆盖旧库(保证新旧库名称一致,接口一致) “接口”→ 重新启动程序
  • 缺点:延时绑定,速度略慢
  • 使用场合:对速度要求不是很强烈的地方都应使用动态库
  • 注意事项:动态库是否加载到内存,取决于程序是否运行。

(6)编译时指定动态库或者静态库编译

如果当前⽂件夹中既有动态库,也有静态库, 静态库与动态库同名的话(比如同时存在和),在编译时,默认会优先使⽤动态库进行编译。

gcc  -o main -L. -l ToolFunc

-L. -l ToolFunc会查找当前⽬录下的库,优先找动态库,若找到,则直接使⽤动态库进⾏编 译,而不使⽤静态库进⾏编译;若未找到动态库,则寻找静态库进行编译;若静态库也未找到,则提示报错。

如何强制使⽤静态库编译:如果在最后 再加上编译选项-static,表示寻找静态链接库⽂件。可强制编译时使⽤静态库,如果不使⽤这个参数,⽽静态库与动态库同名的话,会优 先使⽤动态库

gcc  -o main2  -L . -l ToolFunc -static


end