C语言的动态函数库和静态函数库的生成和使用(linux环境下)

软件开发往往是一个十分庞大的工程.需要消耗大量的脑力.借助别人已经开发好的库,往往能提高效率,下面将介绍如何开发和使用共享的库文件.使用别人已经开发好的库,就像是我们想要建造一辆汽车十分困难,但是如果汽车的各大部件都已经存在并且可以获得,我们要做的工作就是组装,组装过程一定比设计这些部件要轻松.

函数库分为两种静态(static)函数库和动态(shared)函数库.两者都是函数的集合.区别:在编译的时候会把静态函数库的内容加到目标程序中,目标程序具有函数库的代码;而动态函数库是在执行的时候才把函数库中的函数加到目标中,目标程序中并没有函数库的代码.

Linux下面的库文件

动态: xxxx.so

静态: xxxx.a

Windows下面的库文件

动态: xxxx.dll

静态: xxxx.lib

常见C语言的库

Libpng

Libjpeg

Libmysql等

1.使用gcc编译一个动态库文件和使用一个动态库

Gcc -shared 源文件 -o 目标文件

其中-shared表示编译的结果是一个动态库文件,目标文件常常命名为libxxx.so.

例如,建立一个文件test.c和test.h的文件.

Test.c:

#include <stdio.h>

int print()

{

printf("hello this is lib");

}

Test.h

int print();

使用gcc -shared test.c -o libtest.so  (编译的结果最好使用lib开头,调用的时候可以省略)

生成了文件libtest.so的动态函数库(-shared表示生成动态函数库,-o表示生成的目标文件).

写一个程序(在call.c)用来调用这个函数库中的print()

#include "libtest.h"

int main()

{

print();

return 0;

}

编译的时候命令

gcc call.c -ltest -L. -o c

其中-lxx表示调用动态函数库,libtest.so,如果库文件的格式不是libxx.so,也可以使用-l xxx.so

-L. 表示这个函数库在当前文件夹下面

如果把libtest.so复制到/usr/lib或者/usr/local/lib下面,可以使用命令gcc call.c -ltest -o c不需要使用-L.参数.

如果直接运行./c会出现错误

#./c
: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

原因:虽然已经把函数库放到系统库目录或者告知函数库在当前,但是系统会自动去/etc/ld.so.cache中去查找已经记录的函数库,并不是去文件夹下搜索.所以想要使用函数库,还需要使用命令ldconfig去搜索函数库添加到系统ld.so.cache中.

如果在当前的路径下,可以把当前路径添加到/etc/ld.so.conf中,然后运行ldconfig,就可以把当前的文件添加到ld.so.ccache中.

也可以修改临时的系统库变量LD_LIBRARY_PATH.在终端中使用命令

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../  

(shell命令,可以使用echo $LD_LIBRARY_PATH来查看变量,关闭终端在打开就需要重新配置了)

之后,就可以运行了.

#./c

#hello this is lib

ldconfig是动态链接库管理命令.如果想详细了解,可以去仔细查看ldconfig的命令的相关细节.

还有一个命令ldd,他是查看程序需要什么样的动态库.

#ldd c

linux-gate.so.1 =>  (0xb77bd000)

libtest.so => not found

libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75fc000)

/lib/ld-linux.so.2 (0xb77c0000)

2.编译成静态库文件并使用

我们使用上面用到的例子libtest.c和libtest.h,call.c.

首先把libtest.c编译成静态的函数库.

Gcc -c libtest.c   

把libtest.c编译成libtest.o,和不加-c的区别是,-c不进行链接

ar crv libtest.a libtest.o 

Ar是把文件生成静态库.详细参考man ar

编译目标程序

Gcc call.c libtest.a -o c

然后就可以使用./c运行了.

因为静态库在编译的时候就加入了程序中,所以目标编译之后,就不需要xxx.a文件了.

虽然,相比之下静态库比较简单,但是采用静态库的代码往往很大.

猜你喜欢

转载自www.cnblogs.com/qiny1012/p/8910272.html