您的位置:首页 > 运维架构 > Linux

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: