C语言的静态库与共享库

简介: 1库的概念2静态库2-1 静态库的概念2-2 静态库的创建2-2-1 静态库创建的命令2-2-2 静态库创建的准备工作2-2-3 创建静态库的例子2-3 静态库的使用2-3-1 静态库使用的命令2-3-2 静态库使用的例子3共...

1、库的概念

函数库是由系统建立的且有一定功能的函数集合。库中存放函数的名称和对应的目标代码,以及连接过程中所需的重定位信息,但是库中对应的函数的源代码一般是不可见的,而对应的头文件中可以看到它的对外接口(函数原型)。
Linux中标准的C函数库放置在/usr/lib下,以文件形式存放。用户也可以根据自己的所需建立自己的用户函数库。函数库分为静态库(.a)共享库(.so,ShareObj),共享库在windows环境也叫动态链接库(.dll)。

2、静态库

2-1 静态库的概念

静态库是一些.o目标文件的集合,一般以.a形式结尾。静态库在程序链接阶段使用,链接器将程序要用到的函数从库中提取出来,并整合到程序中,程序运行不再使用静态库了。由于每个程序要用到函数都从库提取并整合在一起,所以可执行文件夹会比较大。

2-2 静态库的创建

2-2-1 静态库创建的命令

ar rcs lib库文件名.a 目标文件1 目标文件2 ... 目标文件n
  • r:表示将.o目标文件加入到静态库中;
  • c:表示创建静态库;
  • s:表示生产索引;

2-2-2 静态库创建的准备工作

wu_being@UbuntuKylin1704:~/Code/C$ mkdir lib_test
wu_being@UbuntuKylin1704:~/Code/C$ cd lib_test/
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ l
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ mkdir bin include obj src
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ l
bin/  include/  obj/  src/
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ vim src/mymath_test.c
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ cat -n src/mymath_test.c 
     1  #include <stdio.h>
     2  #include "mymath.h"
     3  
     4  int main()
     5  {
     6      printf("My Pi: %lf"\n, my_pi());
     7      return 0;
     8  }
     9  
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ vim include/mymath.h
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ cat -n include/mymath.h 
     1  #ifndef __MYMATH_H__
     2  #define __MYMATH_H__
     3  
     4  double my_pi(void);
     5  
     6  #endif
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ vim src/mymathfun.c
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ cat -n src/mymathfun.c 
     1  
     2  double my_pi(void)
     3  {
     4      return 3.14159;
     5  }

2-2-3 创建静态库的例子

wu_being@UbuntuKylin1704:~/Code/C/lib_test$ mkdir lib 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o obj/mymathfun.o -c src/mymathfun.c 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ar rcs lib/libmymathfun.a obj/mymathfun.o 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/
libmymathfun.a
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 

或者

wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ar rcs lib/libmymathfun.a src/mymathfun.c
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/
libmymathfun.a
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 

2-3 静态库的使用

2-3-1 静态库使用的命令

gcc -o 可执行文件 调用者的C源文件.c  -Ldir -l库文件名

或者

gcc -o 调用者的目标文件.o -c 调用者的C源文件.c
gcc -o 可执行文件 调用者的目标文件.o -Ldir -l库文件名
  • -Ldir:表示指定库文件所在的路径中,默认在库路径在/usr/lib目录下;
  • -lname:表示库目录的库文件libname.alibname.so。如果库文件不是以lib开头,如hello.a,只能用用hello.a,不能用-lhello
  • 删除静态库文件不会影响到可执行文件的运行。

2-3-2 静态库使用的例子

wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o bin/mymathfun_test src/mymath_test.c -Iinclude -Llib -lmymathfun
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test 
My Pi: 3.141590
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o obj/mymath_test.o -c src/mymath_test.c -Iinclude
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o bin/mymathfun_test obj/mymath_test.o -Iinclude -Llib -lmymathfun
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test 
My Pi: 3.141590
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 

3、共享库(动态链接库)

3-1 共享库的概念

共享库即动态链接库,在linux中以.so(share object)为后缀,在windows中以.dll为后缀。程序开始启动运行时,加载所需的函数,程序运行时也需要共享库的支持。共享库链接出来的文件比静态库要小得多。Linux中所有标准的共享库存放在/usr/lib目录中。

3-2 共享库的创建

3-2-1 共享库的创建命令

gcc -shared -fPCI -o lib库文件名.so 目标文件1,目标文件2,...,目标文件n
  • -shared:表示要创建共享库;
  • -fpci或-fPCI:表示创建产生独立目标代码,具体应用取决于平台;

3-2-2 共享库的创建例子

wu_being@UbuntuKylin1704:~/Code/C/lib_test$
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o obj/mymathfun.o -c src/mymathfun.c 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -shared -fPCI -o lib/libmymathfun2.so obj/mymathfun.o 
gcc: error: unrecognized command line option ‘-fPCI’; did you mean ‘-fPIC’?
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -shared -fPIC -o lib/libmymathfun2.so obj/mymathfun.o 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -shared -fpic -o lib/libmymathfun2.so obj/mymathfun.o 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -shared -fPCI -o lib/libmymathfun2.so obj/mymathfun.o 
gcc: error: unrecognized command line option ‘-fPCI’; did you mean ‘-fPIC’?
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/
libmymathfun.a  libmymathfun2.so
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/ -l
总用量 12
-rw-r--r-- 1 wu_being wu_being 1684 1024 17:31 libmymathfun.a
-rwxr-xr-x 1 wu_being wu_being 8152 1024 20:59 libmymathfun2.so
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 

3-3 共享库的使用

3-3-1 共享库的使用命令

gcc -o 可执行文件 调用者的C源文件.c  -Ldir -l库文件名

或者

gcc -o 调用者的目标文件.o -c 调用者的C源文件.c
gcc -o 可执行文件 调用者的目标文件.o -Ldir -l库文件名
  • 运行可执行文件提示找汪以库文件的解决方案
    1. sudo cp libmymathfun2.so /usr/lib
    2. export LD_LIBRARY_PATH=库文件目录
  • 删除静态库文件会影响到可执行文件的运行!(提示找不到库文件)

3-3-2 共享库的使用例子

wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -shared -fPIC -o lib/libmymathfun2.so src/mymathfun.c
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o bin/mymathfun_test2 src/mymath_test.c -Iinclude -Llib -lmymathfun2
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test2 
./bin/mymathfun_test2: error while loading shared libraries: libmymathfun2.so: cannot open shared object file: No such file or directory
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ sudo mv lib/libmymathfun2.so /usr/lib/
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test2 
My Pi: 3.141590
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ sudo rm -rf /usr/lib/libmymathfun2.so 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/
libmymathfun.a
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -shared -fPIC -o lib/libmymathfun2.so obj/mymathfun.o 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/
libmymathfun2.so  libmymathfun.a
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o bin/mymathfun_test2 -Iinclude src/mymath_test.c -Llib -lmymathfun2
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test2 
./bin/mymathfun_test2: error while loading shared libraries: libmymathfun2.so: cannot open shared object file: No such file or directory
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ export LD_LIBRARY_PATH=lib
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test2 
My Pi: 3.141590
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ echo $LD_LIBRARY_PATH 
lib
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/
libmymathfun2.so  libmymathfun.a
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ rm lib/libmymathfun2.so 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ls lib/
libmymathfun.a
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test2 
./bin/mymathfun_test2: error while loading shared libraries: libmymathfun2.so: cannot open shared object file: No such file or directory
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 

4、不使用库的方法

test1

wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ ls
mymathfun.c  mymath.h  mymath_test.c
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ cat -n mymath_test.c 
     1  #include <stdio.h>
     2  #include "mymath.h"
     3  
     4  int main()
     5  {
     6      printf("My Pi: %lf\n", my_pi());
     7      return 0;
     8  }
     9  
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c 
/tmp/ccRCzDfw.o:在函数‘main’中:
mymath_test.c:(.text+0x5):对‘my_pi’未定义的引用
collect2: error: ld returned 1 exit status
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c mymathfun.c 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ ./a.out 
My Pi: 3.141593
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ vim mymath_test.c 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ cat -n mymath_test.c 
     1  #include <stdio.h>
     2  #include "mymath.h"
     3  #include "mymathfun.c"
     4  
     5  int main()
     6  {
     7      printf("My Pi: %lf\n", my_pi());
     8      return 0;
     9  }
    10  
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ ./a.out 
My Pi: 3.141593
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c mymathfun.c 
/tmp/ccMnE10S.o:在函数‘my_pi’中:
mymathfun.c:(.text+0x0): `my_pi'被多次定义
/tmp/cc89I2rk.o:mymath_test.c:(.text+0x0):第一次在此定义
collect2: error: ld returned 1 exit status
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ 

test2

wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o bin/mymathfun_test src/mymath_test.c src/mymathfun.c 
src/mymath_test.c:2:20: fatal error: mymath.h: 没有那个文件或目录
 #include "mymath.h"
                    ^
compilation terminated.
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ gcc -o bin/mymathfun_test src/mymath_test.c src/mymathfun.c -Iinclude
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ ./bin/mymathfun_test 
My Pi: 3.141590
wu_being@UbuntuKylin1704:~/Code/C/lib_test$ 

Wu_Being博客声明:本人博客欢迎转载,请标明博客原文和原链接!谢谢!
《C语言的静态库与共享库》: http://blog.csdn.net/u014134180/article/details/78335274

Wu_Being 吴兵博客接受赞助费二维码

如果你看完这篇博文,觉得对你有帮助,并且愿意付赞助费,那么我会更有动力写下去。

目录
相关文章
|
1月前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
ly~
|
2月前
|
数据可视化 BI API
除了 OpenGL,还有哪些常用的图形库可以在 C 语言中使用?
除了OpenGL,C语言中还有多个常用的图形库:SDL,适合初学者,用于2D游戏和多媒体应用;Allegro,高性能,支持2D/3D图形,广泛应用于游戏开发;Cairo,矢量图形库,支持高质量图形输出,适用于数据可视化;SFML,提供简单接口,用于2D/3D游戏及多媒体应用;GTK+,开源窗口工具包,用于创建图形用户界面。这些库各有特色,适用于不同的开发需求。
ly~
407 4
|
2月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
7月前
|
C语言 存储
C语言—部分库函数的模拟实现
C语言—部分库函数的模拟实现
|
4月前
|
C语言
C语言中的math库概述
C语言中的math库概述
121 1
|
4月前
|
存储 Serverless C语言
C语言中的标准库函数
C语言中的标准库函数
60 0
|
4月前
|
API 开发工具 C语言
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
C语言与图形界面:利用GTK+、Qt等库创建GUI应用。
215 0
|
6月前
|
存储 移动开发 C语言
技术心得记录:嵌入式开发中常用到的C语言库函数
技术心得记录:嵌入式开发中常用到的C语言库函数
60 1
|
6月前
|
C语言
C语言的标准库:string.h, math.h, stdlib.h
C语言的标准库:string.h, math.h, stdlib.h
|
6月前
|
C语言
【海贼王编程冒险 - C语言海上篇】库函数怎样模拟实现?
【海贼王编程冒险 - C语言海上篇】库函数怎样模拟实现?
37 1