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

Linux中关于静态库和动态库的小结

2011-08-14 15:38 204 查看
Q:编译和链接指令中的库是静态库还是两者皆可?

  一、关于库

  1、按照所有者可以分为两类,一类是系统自带的函数库,一般在/usr/lib 和/lib 下;一类是用户自定义的。

       静态库以.a为后缀名,动态库以.so(shared object)为后缀名。

       而一个库是由若干个文件组成的,静态库文件名以lib开头,以.o为后缀;动态库文件名也以lib开头,不过以.so为后缀。也就是说动态库名和动态库文件名享用同一个后缀名.so。

  2、编译的指令:cc -c -O -Idirname x.c :其中-c表示只编译不链接,-O表示进行优化,-Idirname 指定源文件中用到的头文件的目录,如果只使用了系统提供的头文件例如#include<stdio.h>,则不用该选项;若使用了用户自定义的头文件,例如#include"head.h",则需要指定head.h所在的目录。

      链接指令:cc x.o -Ldirname -lyyy -o x :其中 -Ldirname 指定了要链接的库(静态还是两者都可以?答:静态,动态需要加上-s命令)所在的目录,如果程序只使用了系统库文件,则不用该选项。-lyyy 指定了要链接的库的名字,也就是在dirname目录下或者系统默认的目录下的函数库名libyyy.a。-o表示生成可执行文件,文件名为x。

  二、关于动态库

  1、创建:编译+链接

       编译指令:cc -fPIC -c xxx.c

       链接指令:cc -shared xxx.o -o libxxx.so

       编译完成后生成了libxxx.so文件

  2、使用:

      (1)通过LD_LIBRARY_PATH:

             假如编译生成了a.o目标文件,在链接时使用命令 cc a.o -Ldirname -s libxxx.so -o a进行动态链接,其中dirname是libxxx.so所在的目录。-s 表示进行动态链接,最后-o生成可执行文件a。在运行的时候可能会报错,表示找不到文件,此时需要设置环境变量LD_LIBRARY_PATH的值,指定.so所在目录。也就是说不仅需要在-s 动态链接时指定.so所在的目录,还需要在运行是指定.so所在的目录。就这么简单。

       (2)通过dlopen系列函数完成:

              此时(1):需要在源文件中加入<dlfcn.h>头文件,其中定义了dlopen系列函数。

                    (2):调用dlopen函数以某种方式打开.so文件,同时返回动态链接库的句柄;调用dlsym函数返回指定函数的指针;在返回过程中如果返回失败,那么调用dlerror函数输出错误信息。最后通过使用dlsym函数返回的函数指针来使用动态库提供的功能。

                     (3):编写好加入了dlopen系列函数的源文件之后进行编译和链接,编译的过错和一般文件相同,在链接生成可执行文件时使用cc -a.o -ldl -o a。指令中加入 -ldl 表示使用了dlopen系列函数。最后就可以成功运行了。此时无需关注LD_LIBRARY_PATH的值亦可正确运行!

;----------------------------------------------------

常识区:

1、生成动态链接库是的一个命令 -fPIC 的含义是 Position Independent Code(位置无关代码);

2、库函数包括静态库和动态库,运行在用户态;系统调用则使用操作系统提供的某些功能,运行在内核态。

3、LD_LIBRARY_PATH 用于动态链接库。

;------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息