linux 静态库动态库封装问题
2016-05-04 09:09
609 查看
在Linux下类库主要有静态库和动态库两种库,首先呢,就说说这两种库的差异:
静态库:
在程序连接的时候会自动的连接到程序里,
所以一但编译完成,静态库也就不需要了。静态库通常以.a结尾。
例如:libutil.a libuuid.a libz.a等。
动态库:
在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,
因此在程序运行时还需要动态库存在。通常以.so结尾。如:libz.so。
因此,静态库相对于共享库来说有更高的效率但是也要消耗更多的空间。
值得注意的是,如果既有静态库又有动态库,在编译时默认的使用动态库。
在创建自己的静态库或者动态库时候我想,绝大部分人也都会觉得很轻松,下面就直接贴步骤
静态库:
(1) 编写库文件testlib.c
(2)编写一个头文件用于声明我们使用的函数testlib.h
(3) 编译testlib.c:
gcc -c testlib.c
(4) 用ar创建一个归档文件:
ar crv libfirst.a testlib.o 生成libfirst.a
(5)在某些系统中还要为静态库生成一个内容表
ranlib libfirst.a
(6)然后就可以使用该静态库了
eg:
[root@localhost Source]# vi zyx.c
[root@localhost Source]# gcc -o zyx zyx.c -I./lib -L./lib -lfirst (-static)
[root@localhost Source]# ls
hello HelloWorld.h static.exe zyx
HelloWorld.cpp lib StaticLibTest.c zyx.c
[root@localhost Source]# ./zyx
动态库:
通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h, 三个.c文件:test_a.c、test_b.c、test_c.c
我们将这几个文件编译成一个动态库:libtest.so。
gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
我们已经成功生成了一个自己的动态链接库libtest.so,
下面我们通过一个程序来调用这个库里的函数。假设程序的源文件为:test.c
将test.c与动态库libtest.so链接生成执行文件test: $ gcc test.c -L. -ltest -o test
测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
在使用动态库的时候,还有一点会经常遇到的需要注意:
调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录
通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”
的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作
的就是通过修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。
通常这样做就可以解决库无法链接的问题了
1.修改/etc/ld.so.conf,加入自己的动态库的路径
然后/sbin/ldconfig 使配制文件生效
2。直接把自己的动态库文件拷贝到 /etc/ld.so.conf中的任意路径
3.export LD_LIBRARY_PATH=/home/kui/:$LD_LIBRARY_PAT(=的前后不能有空格)或者export
$LD_LIBRARY_PATH:LD_LIBRARY_PATH=/home/kui/
使用echo $LD_LIBRARY_PATH可以看到路径是否设置成功
上面这些都是最基本的,在工作中,这些往往满足不了我们的需要,比如说,我们生成一个动态库,要依赖与多个动态库或者静态库,或者我生成静态库的时候要依赖于其它的静态库,这个时候怎么弄?
关于依赖于多个静态库或者动态库生成一个动态库的,网上有很多资源,也不多说,直接贴一个示例:
gcc -g Protocol.c -fPIC -shared libadd.a libade.a -o libScanApi.so -I ./ -L ./ -lfrt6 -I
/usr/local/include/libusb-1.0/ -L /usr/local/lib/ -lusb-1.0
在这里面,我生成了一个 libScanApi.so的库,它依赖于静态库 libadd.a
libade.a(静态库如若是自己编译的,在编译时候要加上-fPIC -shared),动态库libfrt6.so和libusb-1.0.so。其中,-I后面接的是库头文件路径, -L后面接的是库路径,如果还有更多的静态库或者动态库需要被依赖,则在后面一次添加
关于静态库,似乎可用的资料就不是那么多了
前不久遇到这样的一个问题,我依赖于几个.c文件和两个静态库的动态库,需要提供一个静态库版本给客户,当时感觉很郁闷,因为两个静态库我都是没有源码的,网上找了许久也没有找到自己想要的,后来求助一大神,终于完美解决。
我现在找不到那个网址了,不过还好保存的还有截图,可以参阅一下,同时也建议,如果要经常使用到静态库,可以先细读一下ar的参数。
其实静态库也就相当于一个压缩包,里面存放的是一些.o文件,把需要的.o放在一起打包,就生成了静态库。ar x A.a则正相反,是把生成A.a的.o文件给解出来,这样,即便是第三方库我们也可以获得其.o。而生成静态库的时候正是依赖于.o文件,所以我们就可以依赖于多个静态库生成一个静态库了。
但是有的时候,貌似这样还会错误,比如我上次用的是libusb-1.0.a的静态库,在解压重新打包编译之后,出现了这样的问题
从错误中,可以很明显的看到clock和pthread,很明显,是缺少pthread库和lrt(实时时钟)库的支持,于是在编译时候在后面加上-lpthread 和-lrt就so easy 解决了
gcc -o tets testScanApi.c -L. -lFP_Ara -lpthread -lrt
静态库:
在程序连接的时候会自动的连接到程序里,
所以一但编译完成,静态库也就不需要了。静态库通常以.a结尾。
例如:libutil.a libuuid.a libz.a等。
动态库:
在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,
因此在程序运行时还需要动态库存在。通常以.so结尾。如:libz.so。
因此,静态库相对于共享库来说有更高的效率但是也要消耗更多的空间。
值得注意的是,如果既有静态库又有动态库,在编译时默认的使用动态库。
在创建自己的静态库或者动态库时候我想,绝大部分人也都会觉得很轻松,下面就直接贴步骤
静态库:
(1) 编写库文件testlib.c
(2)编写一个头文件用于声明我们使用的函数testlib.h
(3) 编译testlib.c:
gcc -c testlib.c
(4) 用ar创建一个归档文件:
ar crv libfirst.a testlib.o 生成libfirst.a
(5)在某些系统中还要为静态库生成一个内容表
ranlib libfirst.a
(6)然后就可以使用该静态库了
eg:
[root@localhost Source]# vi zyx.c
[root@localhost Source]# gcc -o zyx zyx.c -I./lib -L./lib -lfirst (-static)
[root@localhost Source]# ls
hello HelloWorld.h static.exe zyx
HelloWorld.cpp lib StaticLibTest.c zyx.c
[root@localhost Source]# ./zyx
动态库:
通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h, 三个.c文件:test_a.c、test_b.c、test_c.c
我们将这几个文件编译成一个动态库:libtest.so。
gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
我们已经成功生成了一个自己的动态链接库libtest.so,
下面我们通过一个程序来调用这个库里的函数。假设程序的源文件为:test.c
将test.c与动态库libtest.so链接生成执行文件test: $ gcc test.c -L. -ltest -o test
测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
在使用动态库的时候,还有一点会经常遇到的需要注意:
调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录
通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”
的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作
的就是通过修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。
通常这样做就可以解决库无法链接的问题了
1.修改/etc/ld.so.conf,加入自己的动态库的路径
然后/sbin/ldconfig 使配制文件生效
2。直接把自己的动态库文件拷贝到 /etc/ld.so.conf中的任意路径
3.export LD_LIBRARY_PATH=/home/kui/:$LD_LIBRARY_PAT(=的前后不能有空格)或者export
$LD_LIBRARY_PATH:LD_LIBRARY_PATH=/home/kui/
使用echo $LD_LIBRARY_PATH可以看到路径是否设置成功
上面这些都是最基本的,在工作中,这些往往满足不了我们的需要,比如说,我们生成一个动态库,要依赖与多个动态库或者静态库,或者我生成静态库的时候要依赖于其它的静态库,这个时候怎么弄?
关于依赖于多个静态库或者动态库生成一个动态库的,网上有很多资源,也不多说,直接贴一个示例:
gcc -g Protocol.c -fPIC -shared libadd.a libade.a -o libScanApi.so -I ./ -L ./ -lfrt6 -I
/usr/local/include/libusb-1.0/ -L /usr/local/lib/ -lusb-1.0
在这里面,我生成了一个 libScanApi.so的库,它依赖于静态库 libadd.a
libade.a(静态库如若是自己编译的,在编译时候要加上-fPIC -shared),动态库libfrt6.so和libusb-1.0.so。其中,-I后面接的是库头文件路径, -L后面接的是库路径,如果还有更多的静态库或者动态库需要被依赖,则在后面一次添加
关于静态库,似乎可用的资料就不是那么多了
前不久遇到这样的一个问题,我依赖于几个.c文件和两个静态库的动态库,需要提供一个静态库版本给客户,当时感觉很郁闷,因为两个静态库我都是没有源码的,网上找了许久也没有找到自己想要的,后来求助一大神,终于完美解决。
我现在找不到那个网址了,不过还好保存的还有截图,可以参阅一下,同时也建议,如果要经常使用到静态库,可以先细读一下ar的参数。
其实静态库也就相当于一个压缩包,里面存放的是一些.o文件,把需要的.o放在一起打包,就生成了静态库。ar x A.a则正相反,是把生成A.a的.o文件给解出来,这样,即便是第三方库我们也可以获得其.o。而生成静态库的时候正是依赖于.o文件,所以我们就可以依赖于多个静态库生成一个静态库了。
但是有的时候,貌似这样还会错误,比如我上次用的是libusb-1.0.a的静态库,在解压重新打包编译之后,出现了这样的问题
从错误中,可以很明显的看到clock和pthread,很明显,是缺少pthread库和lrt(实时时钟)库的支持,于是在编译时候在后面加上-lpthread 和-lrt就so easy 解决了
gcc -o tets testScanApi.c -L. -lFP_Ara -lpthread -lrt
相关文章推荐
- linux 系统调用如何进入内核模式
- Linux系统调用的实现机制分析
- arm-linux交叉编译bad ELF interpreter
- linux core文件
- Linux script and scriptreplay(三)
- Hyper-V 虚拟设备简介
- Linux远程连接图形界面的几种方法
- Windows原生运行Linux的技术细节
- RHEL 6.0使用CentOS yum源
- linux重定向及nohup不输出的方法
- Linux下ntpdate时间同步
- linux下的时间及时区设置
- linux下的DNS
- linux目录结构详细介绍
- Linux常用命令大全
- 最最实用的30个Linux命令
- Linux Vim编程初体验
- centos 安装arm-llinux 交叉编译器
- Linux 创建修改删除用户和组的方法
- centos安装elasticsearch2.3.2记录