linux库文件编写基础

本文详细介绍静态库和动态库的编写与使用方法,包括静态库的创建与调用过程,动态库的隐式及显式调用方式,并提供具体实例帮助理解。

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

一、静态库的编写和使用

  1、概述

  静态库文件的扩展名一般为.a,其编写步骤很简单。

  ⑴编写函数代码

  ⑵编译生成各目标文件

  ⑶用ar文件对目标文件归档,生成静态库文件。

  注意归档文件名必须以lib打头。

  使用要点:

  ⑴在gcc 的-I参数后加上静态库头文件的路径。

  ⑵在gcc 的-L参数后加上库文件所在目录

  ⑶在gcc 的-l参数后加上库文件名,但是要去掉lib和.a扩展名。

  比如库文件名是libtest.a 那么参数就是 -l test

  2、编写最简单的静态库文件

  编写如下两个文件,注意放在同一目录中

  myalib.h   //静态库头文件

  myalib.c   //静态库实现文件

  //myalib.h 文件的内容

  void test();

  //myalib.c 文件的内容

  #inlcude <stdio.h>

  void test()

  {

        printf("test/n");

  }

      3、制作库文件

  ⑴生成目标文件

  gcc -c myalib.c

  执行完后会生成一个myalib.o文件

  ⑵用ar命令归档,格式为ar -rc <生成的档案文件名> <.o文件名列表>

  再次提醒,归档文件名一定要以lib打头, .a结尾。

  ar -rc libtest.a myalib.o

  执行完后会生成一个libtest.a文件

  4、使用库文件

  ⑴编写一个测试程序main.c,内容为

  //main.c 测试静态库调用的程序

  #include "myalib.h"   //要把函数的头文件包含进来,否则编译时会报错

  int main(int argc,char* argv[])

  {

      test();

      return 0;

  }

  ⑵编译目标文件,注意要把静态库头文件的路径加到-I参数里面

  gcc -I /root/exercise -o main.o -c main.c

  现在生成了一个main.o文件

  ⑶生成可执行文件,注意要把静态库文件的路径加到-L参数里面,

  把库文件名(去掉打头的lib和结尾的.a)加到-l参数后面。如下面所示

  gcc -o main -L/root/exercise   main.o -ltest

  此时就会生成一个名为main的可执行文件

  另外,注意- l参数好象应该加到输入文件名的后面,否则会报错。

  ⑷执行可执行文件查看效果

  执行./main, 输出

  test

  说明执行成功。

二、动态库的编写

  1、概述

  动态库一般以.so结尾,就是shared object的意思.

  其基本生成步骤为

  ⑴编写函数代码

  ⑵编译生成动态库文件,要加上 -shared 和 -fpic 选项 ,

  库文件名以lib开头, 以.so 结尾。

  使用方式分为两种: 隐式调用和显示调用

  隐式调用类似于静态库的使用,但需修改动态链接库的配置文件/etc/ld.so.conf;

  显示调用则是在主程序里使用dlopen、dlsym、dlerror、dlclose等系统函数。

  具体的调用方式会在 "五、动态库的调用" 中详细说明.

  2、编写最简单的动态库文件

  为了便于对照, 我们仍然采用静态库中的文件做例子.

  编写如下两个文件,注意放在同一目录中

  myalib.h   //静态库头文件

  myalib.c   //静态库实现文件

  //myalib.h 文件的内容

  void test();

  //myalib.c 文件的内容

  #inlcude <stdio.h>

  void test()

  {

      printf("test/n");

  }

3、编译生成动态库 ,库文件名以lib开头, 以.so 结尾。

  gcc -fpic -shared -o libtest.so myalib.c

  此时就生成一个libtest.so文件

三、动态库的隐式调用

  隐式调用的含义是代码里不出现库文件名,就是说这个代码和

  调用静态库的代码是类似的。

  1、编写测试文件

  //main.c 测试动态库隐式调用的程序

  #include "myalib.h"   //要把函数的头文件包含进来,否则编译时会报错

  int main(int argc,char* argv[])

  {

      test();

      return 0;

  }

  2、 编译测试程序,与静态库类似,要把头文件的路径加到-I参数里面

  gcc -I /root/exercise -o main.o -c main.c

  现在生成了一个main.o文件

  3、连接生成测试程序

  gcc -o main -L/root/exercise   main.o -ltest

  现在生成了一个main文件

  4、执行测试程序

  ./main

  此时出现提示

  ./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory。

  这个原因就是程序运行时并不知道动态库所在的路径,因此自然找不到。所以一般要把库文件考到系统库目录中/usr/lib/中

四、动态库的显式调用

  显式调用的含义是代码出现库文件名,用户需要自己去

  打开和管理库文件。其要点为:

  ⑴把dlfcn.h系统头文件包含进来

  ⑵用dlopen函数打开库文件,并指定打开方式

  dllope的的第一个参数为共享库的名称,将会在下面位置查找指定的共享库。

  ①环境变量LD_LIBRARY_PATH列出的用分号间隔的所有目录。

  ②文件/etc/ld.so.cache中找到的库的列表,由ldconfig命令刷新。

  ③目录usr/lib。

  ④目录/lib。

  ⑤当前目录。

  第二个参数为打开共享库的方式。有两个取值

  ①RTLD_NOW:将共享库中的所有函数加载到内存

  ②RTLD_LAZY:会推后共享库中的函数的加载操作,直到调用dlsym()时方加载某函数

  ⑶用dlerror()函数测试是否打开成功,并进行错误处理;

  ⑷用dlsym获得函数地址,存放在一个函数指针中

  ⑸用获得的函数指针进行函数调用。

  ⑹程序结束时用dlclose关闭打开的动态库,防止资源泄露。

  ⑺用ldconfig工具把动态库的路径加到系统库列表中

     1、编写测试文件

  //main.c 测试动态库显式调用的程序

  #include<dlfcn.h>      //用于动态库管理的系统头文件

  #include "myalib.h"    //要把函数的头文件包含进来,否则编译时会报错

  int main(int argc,char* argv[])

  {

      //声明对应的函数的函数指针

      void (*pTest)();

      //加载动态库

      void *pdlHandle = dlopen("libtest.so", RTLD_LAZY);

      //错误处理

      if(pdlHandle == NULL )   

         {

          printf("Failed load library/n");

          return -1;

      }

      char* pszErr = dlerror();

      if(pszErr != NULL)

      {

            printf("%s/n", pszErr);

            return -1;

       }

       //获取函数的地址

       pTest = dlsym(pdlHandle, "test");

       pszErr = dlerror();

       if(pszErr != NULL)

       {

             printf("%s/n", pszErr);

             dlclose(pdlHandle);

             return -1;

       }

       //实现函数调用

       (*pTest)();

       //程序结束时关闭动态库

       dlclose(pdlHandle);

        return 0;

  }

  2、编译测试文件 使用-ldl选项指明生成的对象模块需要使用共享库

  gcc -o main -ldl main.c

  执行完后就生成了一个main文件

  3、执行测试程序

  执行 ./main

  输出

  test

  说明成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值