济南做网站互联网公司有哪些,烟台开发区网站,上海网站建设报价方案,免费招商加盟动态库
概述
动态库的扩展名是.so。
动态库是被加载#xff0c;调用的时候是根据内存地址去调用#xff0c;而不是将代码复制到文件中。
动态库可以同时被多个进程使用。
实战案例#xff1a;构建 libmath.so 动态库
准备源文件
calc.h
定义加法#xff1a;int add…动态库
概述
动态库的扩展名是.so。
动态库是被加载调用的时候是根据内存地址去调用而不是将代码复制到文件中。
动态库可以同时被多个进程使用。
实战案例构建 libmath.so 动态库
准备源文件
calc.h
定义加法int add(int a, int b);定义减法int sub(int a, int b);
#ifndef __CALC_H_
#define __CALC_H_int add(int a, int b);
int sub(int a, int b);#endif // __CALC_H_calc.c
简单的实现加法简单的实现减法
#include calc.hint 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_void show(int a, char* op, int b, int res);#endif // __SHOW_H_show.c
#include stdio.h
#include show.hvoid show(int a, char* op, int b, int res){printf(%d %s %d %d\n, a, op, b, res);
}编译C源文件
gcc -c -fpic calc.c
gcc -c -fpic show.c构建动态库
gcc -shared calc.o show.o -o libmath.so使用动态库
main.c
#include stdio.h
#include calc.h
#include show.hint main(){int a 11;int b 22;int res add(a, b);show(a, , b, res);return 0;
}编译并运行文件此时把静态库文件也带上
# 先配置库所在的环境变量
export LD_LIBRARY_PATH$LD_LIBRARY_PATH:.# 编译执行
gcc main.c libmath.so -o main ./main输出结果如下
11 22 33动态加载常用方法
dlopen 方法
语法
void* dlopen(char const** filename, int flag)功能将动态共享库载入内存并获得其访问句柄。
参数
filename动态库路径若只给文件名不带目录则根据LD_LIBRARY_PATH环境变量的值搜索动态库flag RTLD_LAZY延迟加载使用动态库中的符号时才真的加载到内存RTLD_NOW立即加载
返回值成功返回动态库的访问句柄失败返回NULL。
句柄唯一标识了系统内核所维护的动态共享库对象将作为后续函数调用的参数。
dlclose 方法
语法
int dlclose(void * handle)功能从内存中卸载动态库
参数handle动态句柄
返回值成功返回0失败返回非0
所卸载的共享库未必真的会立即从内存中消失因为其他程序可能还需要使用该库。只有所有使用该库的程序都显式或者隐式的卸载了该库该库所占用的内存空间才会真正得到释放。
无论卸载的共享库是否真正被释放传递给close函数的句柄都会在该函数成功返回以后立即失效。
dlerror 方法
语法
char* dlerror(void)功能获取在加载使用和卸载共享库过程中所发生的错误。
返回值有错误则返回指向错误信息字符串的指针否则返回NULL。
使用示例
void* handle dlopen(libmath.so, RTLD_NOW);
if (!handle){fprintf(stderr, dlopen: %s\n, dlerror());exit(EXIT_FAILURE);
}dlsym 方法
语法
void* dlsym(void* handle, char const* symbol)功能从已被加载的动态库中获取特定名称的符号地址
参数
handle 动态库访问句柄symbol 符号名
返回值成功返回给定符号的地址失败返回NULL
该函数 所返回的指针为void*类型需要转型为实际目标类型相一致的指针后才能使用。
实战动态加载 libmath.so 动态库
准备 .so 文件
mkdir lib
mv libmath.so ./lib/
ls lib编写main.c
#include stdio.h
#include dlfcn.hint main(){// get the .so handlevoid* handle dlopen(./lib/libmath.so, RTLD_NOW);if(handle NULL){fprintf(stderr, dlopen error: %s\n, dlerror());return -1;}// get the func addressint (*add)(int, int) dlsym(handle, add);if(add NULL){fprintf(stderr, dlsym error: %s\n, dlerror());return -1;}// use the add funcint value add(11, 22);printf(11 22 %d\n, value);// close the handleif(dlclose(handle)){fprintf(stderr, dlclose error: %s\n,dlerror());return -1;}return 0;
}编译并执行程序
gcc -o main main.c -ldl ./main输出
11 22 33