rootfs根文件系统在Linux下制作动态库

一、Linux如何制作静态库

静态库的本质就是将多个目标文件打包成一个文件

链接静态库的过程就是将库中被调用的代码复制到调用模块中

静态库的扩展名:.a 例如:libXXXX.a

以数学库为例,

cpp 复制代码
/******compute.h*****/
#ifndef _COMPUTE_H
#define _COMPUTE_H
extern int add(int,int);
extern int sub(int,int);
#endif

/******compute.c*****/
#include "compute.h"

int add(int a,int b){
    return a + b;
}
int sub(int a,int b){
    return a - b;
}

/******show.h*****/
#ifndef _SHOW_H
#define _SHOW_H
extern void show(int a,char b,int c ,int d);
#endif

/******show.c*****/
#include "show.h"
#include <stdio.h>
void show(int a,char b,int c,int d){
    printf("%d %c %d %d\n",a,b,c,d);
}
/******main.c*****/
#include "compute.h"
#include "show.h"
#include <stdio.h>
int main(void){
    int a = 123;
    int b = 456;
    show(a,'+',b,add(a,b);
    return 0;
}

制作静态库的步骤

第一步,完成功能需求代码的编写(以数学库为例)

第二步,编译成目标文件,需要编译成.o文件

第三步,将多个目标文件制作成静态库

ar [选项] <静态库文件> [目标文件列表]

-r 将目标插入到静态库中,已存在则更新

-q 将目标文件追加到静态库尾

-d 从静态库中删除目标文件

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

-x 将静态库展开为目标文件
ar -r libmath.a compute.o show.o //将多个目标文件制作成静态库

制作完成后就是使用静态库。使用静态库的步骤:

第一步,完成使用静态库的代码编写(main.c)

第二步,编译并链接静态库

-直接链接静态库

gcc main.c libmath.a //同一路径下

-用-l指定库名 -L指定库路径

gcc main.c -lmath -L<路径>

也可以使用LIBRARY_PATH环境变量指定库路径

export LIBRARY_PATH=$LIBRARY_PATH:<添加的路径>

二、Linux如何制作动态库

动态库和静态库不同,链接动态库不需要将被调用的函数代码复制到包含调用代码的可执行文件中,相反链接器会在调用语句处嵌入一段指令,在该程序执行到这段指令时,会加载该动态库并寻找被调用函数的入口地址并执行。

如果动态库中的代码同时为多个进程所用,动态库在内存的实例只有一份,为所有使用该库的进程所共享,因此动态库亦称共享库。

动态库扩展名.so

例如:libXXXX.so

制作动态库的步骤:

第一步,完成功能需求的代码编写

第二步,编译生成动态库所需的目标文件(.o文件)

gcc -c -fpic .c文件

pic:位置无关码,了解

第三步,将多个目标文件制作成动态库

gcc -shared 多个目标文件 -o libmath.so

制作完成后就是使用动态库。使用动态库的步骤:

第一步,完成使用动态库的代码编写(main.c)

第二步,编译并链接动态库

-直接链接静态库

gcc main.c libmath.so //同一路径下

-用-l指定库名 -L指定库路径

gcc main.c -lmath -L<路径>

也可以使用LIBRARY_PATH环境变量指定库路径

export LIBRARY_PATH=$LIBRARY_PATH:<添加的路径>

此时在运行可执行文件时发现,出现下列问题,解决方法就是链接器没有在运行时链接动态库

运行阶段需要保证LD_LIBRARY_PATH环境变量中包含共享库所在路径用以告知链接器在运行时链接动态库。

export LD_LIBRARY_PATH=&LD_LIBRARY_PATH:<路径>

在可执行程序的链接阶段,并不将所调用函数的二进制代码复制到可执行程序中,而只是将该函数在共享库中的地址嵌入到调用模块中,因此运行时需要依赖共享库。

三、动态库的动态加载

动态加载:在程序执行的过程中,开发人员可以动态加载共享库(什么时候用什么时候加载),这样可以提高内存利用率。

在程序中动态加载共享库需要调用一组特殊的函数,他们被声明于一个专门的头文件中,并在一个独立的库中予以实现。

使用这组函数需要包含此文件,并链接该库

#include <dlfcn.h>

-ldl
函数:dlopen,dlsym,dlclose,dlerror

cpp 复制代码
#include <stdio.h>
#include "compute.h"
#include "show.h"
#include <dlfcn.h>

int main(void){
	//1.将共享库载入内存
	void* handle = dlopen("./libmath.so",RTLD_LAZY);
	if(handle == NULL){
		fprintf(stderr,"error:%s\n",dlerror());
		return -1;
	}
	//2.从共享库中获取函数地址(函数指针)
	int (*add)(int,int) = dlsym(handle,"add");
	if(add == NULL){
		fprintf(stderr,"error:%s\n",dlerror());
		return -1;
	}
	int (*sub)(int,int) = dlsym(handle,"sub");
	if(sub == NULL){
		fprintf(stderr,"error:%s\n",dlerror());
		return -1;
	}
	void (*show)(int,char,int,int) = dlsym(handle,"show");
	if(show == NULL){
		fprintf(stderr,"error:%s\n",dlerror());
		return -1;
	}
	//3.使用
	int a = 123;
	int b = 456;
	show(a,'+',b,add(a , b));
	//4.卸载动态库
	if(dlclose(handle)){
		fprintf(stderr,"error:%s\n",dlerror());
		return -1;
	}
}

四、rootfs根文件系统在Linux下制作动态库

第一步,完成功能需求文件编写。

第二步,编译成目标文件,

交叉编译器 -c -fpic

第三步, 将多个目标文件制作成动态库

交叉编译器 -shared 目标文件 -o libxxx.so

第四步,使用文件编写,

交叉编译器 使用文件 -l动态库名 -L路径 -o 可执行文件

最后便是路径选择,参照制作动态库

相关推荐
Xue丶25 分钟前
Linux服务器搭建SVN
linux·服务器·svn
sukalot30 分钟前
windows C#-创建记录类型(下)
java·服务器·前端
qichengzong_right1 小时前
树莓派(Raspberry Pi)picotool
linux·c++·单片机
北漂IT民工_程序员_ZG2 小时前
Linux设置静态IP
linux·运维·tcp/ip
cj_eryue2 小时前
linux设置主机名
linux·运维·服务器
AirDroid_cn2 小时前
投屏软件有没有Linux版本?怎样让两台Linux(远程)相互投屏?
linux·运维·服务器·电脑投屏·远程投屏
五月高高2 小时前
Linux 实现自动登陆远程机器
linux·运维
不会调制解调的猫2 小时前
笔记|M芯片MAC (arm64) docker上使用 export / import / commit 构建amd64镜像
服务器·笔记·macos·docker·容器
小小不董3 小时前
Oracle OCP认证考试考点详解082系列19
java·运维·服务器·数据库·oracle·dba