linux环境中静态库与动态库(共享库)的生成与使用

本文详细介绍了在Linux环境下如何生成和使用静态库(.a)和动态库(.so),包括编译源文件、创建库文件、调用库函数的步骤,并提到了dlopen和dlsym等函数在动态加载库时的作用。同时,对比了静态库和动态库在运行时的差异以及环境变量的配置要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一  静态库的生成步骤:

   1 写源程序,以PrintS.c为例,保存退出。


   2 编译源程序,得到目标文件(.o文件)。


     gcc -c 源文件名

    例:PrintS.c

 #include <stdio.h>
 void printS(){
     printf( " *\n");
     printf( "***\n");
     printf( " *\n");
 }

通过以下命令生成.o目标文件PrintS.o

# gcc -c PrintS.c  


   3 打包生成静态库文件 


   ar -r lib名字.a xx.o (.o文件可以多个)
   库文件名字 命名规范:以lib开头,以 .a结束

通过以下命令生成静态库文件 libPrintS.a

# ar -r libPrintS.a PrintS.o

   4 静态库的调用步骤:


   1 写调用的源程序 test.c ,保存退出
   2 编译代码,生成 .o文件。
   3 连接test.o 和 静态库,连接方式有三种:
    a) gcc test.o lib名字.a (直接连)
    b) 先配置环境变量LIBRARY_PATH,把静态库文件所在的路径配置进去,然后:
     gcc test.o -l库名字 (库名字去掉lib和.a)
    c) gcc test.o -l库名字 -L库路径

abc里选一个,比如用a中的直接链接,这时,当前目录应该有

PrintS.c  PrintS.o   test.c  test.o  libPrintS.a

接着,在test.c里调用printS()函数,输入命令

# gcc test.o libPrintE.a 

#./a.out

root@ley: ~/myStudy/PrintTest$ ./a.out
 *
***
 *

 二 共享库的生成步骤:


   1 编写源程序,以PrintE.c为例,保存退出

 #include <stdio.h>
 void printE(){
     printf(" *\n");
     printf("* *\n");
     printf(" *\n");
 }


   2 编译源程序,生成 .o文件PrintE.o

  gcc -c -fpic PrintE.c (不写-fpic也行)

root@ley: ~/myStudy/PrintTest$ gcc -c -fpic PrintS.c


   3 生成共享库文件(.so)

    gcc  -shared add.o -olib名字.so
    当文件较多时,头/源文件需要规范

root@ley: ~/myStudy/PrintTest$   gcc  -shared PrintS.o -olibPrintS.so

  4  共享库的使用步骤


   共享库的使用步骤 与 静态库基本相同。
  注:共享库的连接方式和静态库一样,但在运行时需要额外配置环境变量 LD_LIBRARY_PATH,否则就找不到库文件。
  export LD_LIBRARY_PATH=. 表示引用当前目录为查找库文件的路径

  ldd 命令可以查看共享库的调用关系,如键入 ldd  库文件名,则会显示库依赖关系, libc.so.6 就是c的共享库

root@ley:~/myStudy/PrintTest$ ldd libPrintS.so
        linux-vdso.so.1 =>  (0x00007ffc1e4f9000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9c0aa26000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f9c0aff2000)
root@ley:~/myStudy/PrintTest$ 

三 程序中使用动态库/共享库

就像打开一个文件一样的使用,类似fopen fclose那套文件操作
   步骤:
   1 打开一个共享库文件。dlopen()
   2 在打开的共享库文件中获取一个函数。dlsym()
   3 执行函数   func_in_ld_lib()
   4 关闭共享库文件。dlclose()
dlerror() 处理错误信息

以上调用动态库时,test.c中就是按照这个顺序,调用自定义函数 printE()

test.c:

 #include <stdio.h>
 #include <stdlib.h>
 #include <dlfcn.h>
 int main(){
     void* handle;
     void (*print)();
     char* error;
     handle = dlopen("libPrintE.so",RTLD_NOW);
     if(!handle){
         fprintf(stderr,"%s\n",dlerror());
         exit(EXIT_FAILURE);
     }
     dlerror();
     print = (void (*)())dlsym(handle,"printE");
     error = dlerror();
     if(error != NULL)
     {
         fprintf(stderr,"%s\n",error);
         exit(EXIT_FAILURE);
     }
     print();//调用printE()
     dlclose(handle);
     exit(EXIT_SUCCESS);
 }

 

  4  共享库的使用步骤


   共享库的使用步骤 与 静态库基本相同。
  注:共享库的连接方式和静态库一样,但在运行时需要额外配置环境变量 LD_LIBRARY_PATH,否则就找不到库文件。
  export LD_LIBRARY_PATH=.

  再说下函数dlopen() 它有两个参数,第一个参数是文件名,第二个参数必须是:RTLD_LAZY 或 RTLD_NOW,

  区别:
  RTLD_LAZY  - 延迟加载,open时不真正加载,到使用时再加载。
  RTLD_NOW  - 现在加载,open的同时完成加载

 而 dlerror()在调用 dlopen/dlsym/dlclose之后立刻调用,效果:如果上面的函数出现错误,返回错误信息,如果没有错误,返回NULL。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值