linux下的库(so,a)编译流程

上一篇 / 下一篇  2012-09-04 10:08:24 / 个人分类:LINUX环境高级编程

    总结一下上周讲的库的编译流程。 linux下的库作用 对于编程人员就不必说了吧,linux下有两种库:动态库(共享库)和静态库

   1.两者区别:

    静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。

动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库(共享库)的实例。

    静态库和共享库的最大区别,静态情况下,把库直接加载到程序中,而共享库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。

    静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在

   2.静态库

     2.1 基础概念与相关命令

      a:库名格式lib<name>.a,例如libmytest.a

      b:ar命令创建静态库文件

          d -----从指定的静态库文件中删除文件

          m -----把文件移动到指定的静态库文件中

          p -----把静态库文件中指定的文件输出到标准输出

          q -----快速地把文件追加到静态库文件中

          r -----把文件插入到静态库文件中

          t -----显示静态库文件中文件的列表

          x -----从静态库文件中提取文件

      还有多个修饰符修改以上基本选项,详细请man ar 以下列出三个:

          a -----把新的目标文件(*.o)添加到静态库文件中现有文件之后

          b -----***************************************之前

          v -----使用详细模式

         ar 命令的命令行格式如下:

          ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files... 参数archive定义库的名称, files是库文件中包含的目标文件的清单, 用空格分隔每个文件

       cc 参数cc   -l把库做链接,静态库名称-L制定静态库路径

      2.2 静态库制作及编译流程:

        2.2.1.首先我们编写一个test.c程序代码,内容如下:

        //#include<stdio.h>

         int test(void){
            printf(" xiaolin hello");

          }

        2.2.2.编译test.c生成test.o文件

         cc test.c -c

        执行完成之后会生成一个test.o的二进制文件

        2.2.3.把.o文件打成.a静态库文件

       ar crs libmytest.a test.o

                   ar操作可以跟多个.o文件,需要空格,一起打成 mytest,使用ar -t libmytest.a   显示库包含的.o文件 

        2.2.4.进行静态库编译并执行

        编写一个man.c程序代码,内容如下:

       int main(int argc,char **argv){

                   printftest();}

        编译main.c加载静态库

       cc main.c -lmytest -L.

                  -l静态库名称  -L静态库路径 .指当前目录

                  编译完成执行./a.out输出xiaolin hello

           3.动态库(共享库so)

               

                3.1 基础概念与相关命令

                   a:库名格式lib<name>.so,例如libmyshare.so

                   b:设置环境变量export LD_LIBRARY_PATH=`pwd` 

                  c:   重要的dlfcn.h头文件

           LINUX下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接库的函数的原型。下面详细说明一下这些函数。

       3.c.1 dlerror

  原型为: const char *dlerror(void);

  当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

     3.c.2 dlopen

  原型为: void *dlopen (const char *filename, int flag);

  dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

  filename: 如果名字不以/开头,则非绝对路径名,将按下列先后顺序查找该文件。

  (1) 用户环境变量中的LD_LIBRARY值;

  (2) 动态链接缓冲文件/etc/ld.so.cache

  (3) 目录/lib,/usr/lib

  flag表示在什么时候解决未定义的符号(调用)。取值有两个:

  1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。

  2) RTLD_NOW : 表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。

  dlopen调用失败时,将返回NULL值,否则返回的是操作句柄。

  3.c.3 dlsym : 取函数执行地址

  原型为: void *dlsym(void *handle, char *symbol);

  dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。由此地址,可以带参数执行相应的函数。

  如程序代码: void (*add)(int x,int y); /* 说明一下要调用的动态函数add */

  add=dlsym("xxx.so","add"); /* 打开xxx.so共享库,取add函数地址 */

  add(89,369); /* 带两个参数89和369调用add函数 */

  3.c.4 dlclose : 关闭动态链接库

                 3.2静态库制作及编译流程:

                     3.2.1首先生成 具有地址无关代码(PIC).o文件,使用上个例子的test.c文件演示gcc -fPIC test.c -c  会生成test.o文件

                    3.2.2生成so共享库

            gcc -shared test.o -o libmytest.so

                           检查共享库是否生成是否正确ldd libmytest.so

                    3.2.3编写main.c文件并编译

                           #include<stdio.h>
                          #include<stdlib.h>
                          #include<dlfcn.h>
                           int (*xiaolin)(void);
                          int main(int agrc,char *argv){

                           //打开共享库
                             void *handle = dlopen("libmytest.so",RTLD_LAZY);
                                                         //                                    RTLD_NOW
                             if(handle == (void *)0){
                             fputs(dlerror(),stderr);
                             exit(-1);
                             }
                             xiaolin= dlsym(handle,"test");

              //取test函数地址赋给xiaolin函数,此时xiaolin函数具有test函数功能
                              printf("%d",xiaolin());
                             return 0;
                             }

                              dlclose(handle );//关闭共享库

                    3.2.4 生成可执行文件cc main.c -ldl 

                    3.2.5执行./a.out   可能提示 No such file ,因为环境变量问题,先查看环境变量执行env 如果没有 LD_LIBRARY_PATH 需要设置这个变量,执行export LD_LIBRARY_PATH=`pwd` 具体查看http://www.51testing.com/?uid-466471-action-viewspace-itemid-822972 ,查看 LD_LIBRARY_PATH执行echo $LD_LIBRARY_PATH 如果存在的话 再执行./a.out   应该输出 xiaolin hello


TAG:

 

评分:0

我来说两句

Open Toolbar