Linux动态库的参数化

工程问题

提出这么一个问题:A公司为B公司的一条自动化流水线开发一个检测装置,B公司要求可以检测流水线最终的产品是否合格。具体是:

  • 第一版需要检测产品的涂层颜色是否均匀、外观是否有破损两个指标。
  • 系统上线运行后,支持B公司可以自主增加新的检测项目。

这个工程需求,简单地讲就是需要A公司开发的检测系统,能自动链接目前尚未出现的、未来的接口,这就需要A公司不是开发出检测外观、涂层颜色等具体功能的软件,而是要给B公司提供一个具备可拓展的软件“框架”,使得B公司后续可以按照自己的实际需求来拓展检测装置的功能。


动态加载库

动态库最大的优点,是将链接推迟到运行时,由于运行时才链接动态库,这就给链接的目标留下了选择的空间。结合以上工程需求,可以让程序在运行的时候,为其指定要链接的动态库,以达到可以按需链接动态库的目的,这种做法称为动态库的动态加载。

具体做法如下:

  • 约定好函数接口,比如 void detection()
  • 将各个不同需求的实现代码封装到不同的库中,比如libcolor.so、libshape.so
  • 编写相应配置文件,指定程序在启动后要链接的具体的库

具体实现

  1. 接口实现:
// a.c
void detection()
{
    printf("正在检测颜色是否均匀...\n");
}

// b.c
void detection()
{
    printf("正在检测外观是否破损...\n");
}
  1. 将不同的功能模块制作成动态库:
gec@ubuntu:~$ gcc a.c -o a.o -c -fPIC
gec@ubuntu:~$ gcc -shared -fPIC -o libcolor.so a.o
gec@ubuntu:~$ 
gec@ubuntu:~$ gcc b.c -o b.o -c -fPIC
gec@ubuntu:~$ gcc -shared -fPIC -o libshape.so b.o
gec@ubuntu:~$ 
gec@ubuntu:~$ ls
libcolor.so  libshape.so
  1. 编写一个配置文件,指定程序需要加载的动态库:
gec@ubuntu:~$ cat config
libcolor.so
  1. 读取配置文件,并根据指示加载指定的动态库:
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>

#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>

int main(int argc, char **argv)
{
	// 读取配置文件
	FILE *fp = fopen("config", "r");
	char *lib = calloc(1, 30);
	fgets(lib, 30, fp);
	fclose(fp);

	// 根据配置文件打开指定的库
	void *handle = dlopen(strtok(lib, "\n"), RTLD_NOW);
	if(handle == NULL)
	{
		printf("加载动态库[%s]失败:%s\n", lib, strerror(errno));
		exit(0);
	}

	// 在库中查找事先约定好的接口
	void (*detect)(void);
	detect = dlsym(handle, "detect");
	if(detect == NULL)
	{
		printf("查找符号[%s]失败:%s\n", "detect", strerror(errno));
		exit(0);
	}

	// 潇洒地调用该接口
	detect();
}

代码解析

打开和关闭动态库,获取动态库的操作句柄:
正文-dlopen与dlclose.png

关键点:

  • RTLD_LAZY意味着打开动态库时,并不立即解析库中的函数符号的内存位置,而是等待程序实际调用时才临时去解析。
  • RTLD_NOW与上述含义相反,它意味着打开动态库时就立即解析库中的函数符号的内存位置。
  • 不管是LAZY还是NOW,库中的静态数据符号都将被立即解析。
    正文-dlsym.png

关键点:

  • 该函数用于在动态库中获取指定的函数入口地址。

选自:粤嵌-嵌入式课堂笔记

联系人:18028569040(曾小美老师·微信)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

干燥剂007860

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值