2.2.9生成动态链接库的一些步骤

参考资料

Linux网络编程
比较好的静态库和动态库博客

2.2.9生成动态链接库的一些步骤

先给出一些命令的介绍和说明

文件的扩展名
编译器的说明

默认的环境的路径

文件

  • main.c

  • string.c

一些链接过程的回顾
单个文件
gcc filename.c
没有指定生成文件的名字,所以生成a.out.

编译生成目标文件的话

4 指定生成的目标文件的名字

-c 生成目标文件

gcc -c -o test.o hello.c

目标文件是多文件组织的基本单元,可以重定位,即确定在一个大的程序组织中的地址。

5多文件编译

源文件string.c

/*string.c*/
#define ENDSTRING '\0'					/*定义字符串*/
int StrLen(char *string)
{
  int len = 0;
  
  while(*string++ != ENDSTRING)			/*当*string的值为'\0'时,停止计算*/
    len++;
  return len;		 					/*返回此值*/
}

源文件main.c

/*main.c*/
#include <stdio.h>
extern int StrLen(char* str);						/*声明Strlen函数*/
int main(void)
{
  char src[]="Hello Dymatic";						/*字符串*/
  printf("string length is:%d\n",StrLen(src));		/*计算src的长度,将结果													   打印出来*/
  return 0;
}

编译运行

gcc -o test string.c main.c

执行编译出来的可执行文件

./test

可以分解为如下过程

gcc -c string.c main.c
gcc -o test string.o main.o

6查看预处理

-E会告诉编译器进行预编译操作,
输出中间文件

会引入头文件,替换宏定义

gcc -E string.c
gcc -o string.i -E string.c

7编译成汇编语言

文字描述

gcc -S string.c

8生成和使用静态链接库

静态库是obj文件的集合,以.a为后缀,由程序ar(archive)生成,不用重新编译程序库代码的情况下,重新链接,缺点应该是比较大,会导致生成的程序很大。

  1. 生成静态链接库
    在这里插入图片描述
> ar rcs libMyTest.a *.o       # 将所有.o文件打包为静态库,r将文件插入静态库中,c创建静态库,不管库是否存在,s写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。
> mv libMyTest.a ../lib         #将静态库文件放置lib文件夹下 
> nm libMyTest.a          #查看库中包含的函数等信息
ar -rcs libstr.a string.o
  1. 使用静态链接库
    使用静态链接库
gcc -o test main.c libstr.a
  • 使用 "-l 库名"库名是不包含函数库和扩展名的字符串,例如编译main.c链接静态库libstr.a
    省去了前缀lib,和后缀.a
gcc -o test main.c -lstr

执行的说明
默认路径
-L参数指定到哪个附加路径下面去寻找共享库
易错

gcc -o test main.c -L ./-lstr

9 生成动态链接库26

在这里插入图片描述

  1. 生成动态链接库
    在这里插入图片描述
    -shared是制作动态库的关键字
gcc  -shared -fPCI  -o libstr.so  string.c  

版本的绑定,建立软连接

g++ -shared -Wl,-soname libstr.so -o libstr.so.1 string.c

在这里插入图片描述

参考

-Wl 告诉编译器将后面的参数传递到连接器。而 -soname 指定了 共享库的 soname这个soname的存在是为了兼容方便。
比如:
  有一个程序ap1,以及一个库libtest.so.1
  ap1启动的时候需要libtest.so.1
    如果链接的时候直接把libtest.so.1传给了ap1,那么将来库升级为libtest.so.2的时候,ap1仍然只能使用libtest.so.1的代码,并不能得到升级的好处。而如果指定了soname为libtest.so,那么ap1启动的时候将查找的就是libtest.so而不是其在被链接时实际使用的库libtest.so.1这个文件名。

  在开始时我们建立一个链接:ln -sf libtest.so.1 libtest.so
而在库升级后,我们重新:ln -sf libtest.so.2 libtest.so即可,这样ap1不需要任何变动就能享受升级后的库的特性了。而libtest.so.1,libtest.so.2可以同时存在于系统内,不必非得把libtest.so.2的名字改成libtest.so.1

  1. 动态链接库的配置
      动态链接库不能随意使用,要在运行的程序中使用,指定系统的动态链接库搜索路径。系统配置文件/etc/ls.so.conf 是动态链接库搜索路径的配置文件
    查看内容
cat /etc/ld.so.conf

在这里插入图片描述
3. 动态链接库的管理
idconfig在系统默认搜索路径和动态链接库配置问及那中所列出的目录里搜索动态链接库,搜索后见结果写入缓存文件/etc/ld.so.cache

  • 命令和参数
    在这里插入图片描述

    • 常用的命令组合
      • 列出缓存文件的动态库列表 ldconfig -p
        在这里插入图片描述

      • ldconfig -v 将ldconfig 扫描的信息输出到终端
        在这里插入图片描述
          指定扫描的 目录
        添加用户的lib
        在这里插入图片描述

    1. 使用动态链接库
      使用 -l 库名的方式下面的命令将源文件main.c编译成可执行文件test,并链接库文件libstr.a或者libstr.so
 gcc -o test main.c -L  ./ -lstr

可能遇到的问题和解决方法
没有找到动态链接库造成的。
编译时链接和动态链接的注册有区别。
在这里插入图片描述

export LD_LIBRART_PATH=/example/ex02: $LD_LIBRARY_PATH

使用ld-Linux.so.2来加载程序
使用链接命令来链接 ,动态库路径和程序名
在这里插入图片描述

10动态加载库

动态加载库和动态链接库不同,可以使用程序控制
在这里插入图片描述

  1. 打开动态库的函数dlopen()
    在这里插入图片描述

  2. 获得函数指针dlsym()
    获得动态链接库中指定函数的指针,使用指针进行操作
    在这里插入图片描述
    handle是文件句柄,是第一个函数的返回值。
    在这里插入图片描述

  3. 使用动态加载库的例子

/*动态加载库示例*/
#include <dlfcn.h>/*动态加载库库头*/
#include <stdio.h>
int main(void)
{
  char src[]="Hello Dymatic";					/*要计算的字符串*/
  int (*pStrLenFun)(char *str);					/*函数指针*/
  void *phandle = NULL;							/*库句柄*/
  char *perr = NULL;							/*错误信息指针*/
  phandle = dlopen("./libstr.so", RTLD_LAZY);	/*打开libstr.so动态链接库*/
  /*判断是否正确打开*/
  if(!phandle)									/*打开错误*/
  {
    printf("Failed Load library!\n");			/*打印库不能加载信息*/
  }
  perr = dlerror();								/*读取错误值*/	
  if(perr != NULL)								/*存在错误*/
  {
    printf("%s\n",perr);
    return 0;									/*正常返回*/
  }
  
  pStrLenFun = dlsym(phandle, "StrLen");		/*获得函数StrLen的地址*/
  perr = dlerror();								/*读取错误信息*/
  if(perr != NULL)								/*存在错误*/
  {
    printf("%s\n",perr);						/*打印错误函数获得的错误信息*/
    return 0;									/*返回*/
  }
  
  printf("the string length is: %d\n",pStrLenFun(src)); 													/*调用函数pStrLenFunc计算字符串的长度*/
  dlclose(phandle);					/*关闭动态加载库*/
  return 0;
}

在这里插入图片描述
 说明 -ldl就是对 libdl.so 的使用
就是包含这四个函数的库

  • dlopen//打开一个动态库
  • dlsym//在打开的动态库里找一个函数
  • dlclose//关闭动态库
  • dlerror//返回错误

11 GCC常用选项

头文件路径
加载库路径
警告信息
调试

  1. -DMACRO 选项在这里插入图片描述

  2. GCC的常用选项和含义
    比较多,以后总结

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值