0
点赞
收藏
分享

微信扫一扫

程序库的制作和使用


库的概念

  • 库是二进制文件,包含的代码可被调用
  • 标准C库、数学库、线程库……
  • 库有源码,可下载后编译;也可以直接安装二进制包
  • 系统默认库的位置​​/lib​​​ ​​/usr/lib​
  • 库是事先编译好的,可以复用的代码
  • win和Linux库不兼容
  • LInux下包含静态库和共享库

静态库

优缺点

  • 编译(链接)时把静态库中的相关代码复制到可执行文件中
  • 程序 中以包含代码,运行是不再需要静态库
  • 程序运行时无须加载库,运行速度更快
  • 占用更多磁盘和内存空间
  • 静态库升级后,程序需要重新编译链接

静态库的创建

  • 确定库中函数的功能、接口
  • 编写库源码hello.c

#include <stdio.h>

void hello(void)
{
puts("量子孤岛");
return;
}

  • 编译生成目标文件

$ gcc -c hello.c -Wall

  • 创建静态库hello

$ ar crs libhello.a hello.o

注意:静态库名称lib**.a是固定格式,**是库名

  • 查看库中符号

$ nm libhello.a 

>>>>>
hello.o:

0000000000000000 T hello
U puts

链接静态库

  • 编写应用程序

#include <stdio.h>

void hello(void);

int main()
{
hello();
return 0;
}

  • 编译test.c并链接静态库libhello.a

$ gcc -o test test.c -L. -lhello

-l:指定链接库的名称
-L:指定链接库的路径

编译器默认链接C库

删除库程序依然能运行,因为静态库代码会被复制到程序中。

共享库

特点

  • 编译(链接)时仅记录用到哪个共享库中的哪个符号,不复制共享库中相关代码
  • 程序不包含库中代码,尺寸小
  • 多个程序可共享同一个库
  • 程序运行时才会加载库
  • 库升级方便,无须重新编译程序

共享库的创建

1. 确定库中函数的功能、接口
2. 编写库源码hello.c bye.c

#include <stdio.h>
void bye(void)
{
puts("bye!");
}

3. 编译生成目标文件

$ gcc -c -fPIC hello.c bye.c -Wall

-fPIC:生成位置无关代码

4. 创建共享库common

$ gcc -shared -o libcommon.so.1 hello.o bye.o

说明:
.so:表示共享库文件,.数字——表示库的版本
命名规则:lib<库名>.so.x

5. 为共享库文件创建链接文件

$ ln -s libcommon.so.1 libcommon.so

目的就是编译器在编译时能找到共享库
版本号的好处就是一个库可以有不同的版本,.so指向哪一个文件就调用哪一个库

为库提供头文件,更加规范一些

$ gcc -o test test.c -L. -lcommon

这里和静态库是一样的,怎么区分呢?
gcc会优先链接共享库,如果不存在则链接静态库,如果静态库也没有,就会报错。
加上-static选项,即为直接链接静态库

出现:

./test: error while loading shared libraries: libcommon.so: cannot open shared object file: No such file or directory

因为当前目录没有在系统的搜索目录中

执行:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

如何找到共享库?

  1. 把库拷贝到/usr/lib和/lib目录下
  2. 在LD_LIBRARY_PATH环境变量中添加库所在路径,缺点是重开shell失效
  3. sudo vim /etc/ld.so.conf.d/*conf文件,sudo ldconfig刷新
    就是添加新文件,随便起名字,然后把库的目录添加进去
    /home/linux/io/lib/share

然后刷新

程序库的制作和使用_共享库


举报

相关推荐

0 条评论