Linux动态库应用
2015-10-09 23:50
465 查看
Linux动态库应用
Linux动态库应用简介:
动态库调用方式一
动态库调用方式二
简介:
动态库在编程过程中是一个很重要的技术,在实际开发过程中,我们在设计各模块时,常常会用到一些通用的功能,如文件处理,网络接口等。这时候,我们可以有两种选择:一种是用动态链接技术,一种是静态链接技术。动态链接,顾名思义,就是在程序运行时调用动态库中的函数。静态链接,则是在编译时就已经把代码拷贝到程序中。相比来说,动态库更节省空间与资源,但静态库调用速度更快,因为它是直接编译进程序中;静态库还有一个缺点是当一个静态库被修改时,整个涉及的模块都要重新编译,这对软件更新还说是一个很大的问题,而动态库则只需要更新库文件就可以完成更新。动态库调用方式一
库函数介绍:函数原型 | 说明 | 备注 |
---|---|---|
void *dlopen(const char *filename, int flag) | 该函数将打开一个新库,并把它装入内存 | 头文件:dlfcn.h,编译时需加上-ldl参数(gcc/g++) |
char *dlerror(void) | 库函数报错函数 | |
void *dlsym(void *handle, const char *symbol) | 获取库符号的地址 | |
void *dlclose(void *handle) | 关闭库与dlopen对应 |
/****************************func.c***********************************/ #include <stdio.h> void func() { printf("this is call func"); }
/****************************func.h***********************************/ #ifdef __FUNC_H__ #define __FUNC_H__ void func(void); #endif
用如下命令生成一个动态链接库:
linux@skytrails$ gcc -shared -fPIC -o libfunc.so func.c
设计调用libfunc.so的主函数:
/****************************main.c***********************************/ #include <dlfcn.h> #include <stdlib.h> #include <stdio.h> #include "func.h" int main() { void * handle; void (*pfunc)(void); char *error; handle = dlopen("libfunc.so", RTLD_NOW); if (NULL == handle){ printf("call dlopen failed!"); exit(0); } pfunc = (void(*)(void))dlsym(handle, "func"); if (NULL == pfunc){ error = dlerror(); printf("call dlsym failed!%s", error); } else{ (*pfunc)(); } printf("\n"); pfunc = (void(*)(void))dlsym(handle, "func1"); if (NULL == pfunc){ error = dlerror(); printf("call dlsym failed!%s\n", error); } else{ (*pfunc)(); } printf("\n"); pfunc = (void(*)(void))dlsym(handle, "func2"); if (NULL == pfunc){ error = dlerror(); printf("call dlsym failed!%s\n", error); } else{ (*pfunc)(); } printf("\n"); pfunc = (void(*)(void))dlsym(handle, "func3"); if (NULL == pfunc){ error = dlerror(); printf("call dlsym failed!%s\n", error); } else{ (*pfunc)(); } printf("\n"); pfunc = (void(*)(void))dlsym(handle, "func4"); if (NULL == pfunc){ error = dlerror(); printf("call dlsym failed!%s\n", error); } else{ (*pfunc)(); } printf("\n"); exit(1); }
链接libfunc.so生成可执行文件:
linux@skytrails$ gcc -shared -fPIC main.c -o main -ldl
在命令行下运行可得到:
linux@skytrail$ ./main call dlsym failed!./libfunc.so: undefined symbol: func this is call func1 this is call func2 this is call func3 this is call func4
完整的编译可以制作成简易的makefile文件:
################################ makefile文件 ################################ all:libfunc.so main libfunc.so:func.c func.h gcc $< -o libfunc.so -fPIC -shared main:main.c gcc $< -o main -ldl
注意事项:
调用库函数dlopen,dlsym,dlclose时要加载库libdl.so。
linux为程序动态库提供了5种搜索的路径,系统默认不搜索当前目录,可以根据下文的动态库搜索路径自已选择一种方式,否则找不到指定库文件。
如果把func.c文件后缀改成.cpp,则会以c++方式编译,这时会调用dlsym失败,提示找不到func*符号。这里因为c/c++的差异,需要在函数名前指定为extern "c"。
动态库搜索路径
优先级 | 路径 | 备注 |
---|---|---|
1 | DT_RPATH(ELF可执行文件中动态段) | 编译目标代码时,对编译器(gcc/g++)加入链接参数-Wl,-rpath指定动态库搜索路径。优先级最高 |
2 | LD_LIBRARY_PATH | Linux环境变量 |
3 | /etc/ld.so.conf中指定动态库路径 | 不同Linux系统文件不一样(debain)。这里是debain系统 |
4 | /lib | 默认动态为搜索路径 |
5 | /usr/lib |
动态库调用方式二
简介:第二种方式其实前面已经应用了。就是libdl.so的调用,在调用库函数dlopen等时需要用到。下面用一个代码实例来说明其应用。
代码示例(libfunc.so库复用上面代码,makefile与main.c作一点小小的修改即可):
/******************************* main.c ******************************/ #include <stdlib.h> #include <stdio.h> #include "func.h" int main() { func1(); printf("\n"); func2(); printf("\n"); func3(); printf("\n"); func4(); printf("\n"); exit(1); }
################################ makefile文件 ################################ all:libfunc.so main libfunc.so:func.c func.h gcc $< -o libfunc.so -fPIC -shared main:main.c gcc $< -o $@ -L. -lfunc
执行make
linux@skytrails$ make gcc func.c -o libfunc.so -fPIC -shared gcc main.c -o main -L. -lfunc
执行程序
linux@skytrails$ ./main this is call func1 this is call func2 this is call func3 this is call func4
相关文章推荐
- Win7与虚拟机中Linux的ping通设置
- 马哥Linux运维笔记----7
- Centos 安装旧版php5.2
- centos的zabbix自定义脚本
- Linux的DNS的53端口
- Linux下备份项目,保持结构,选择性复制部分文件
- Linux C编程(2) dgb调试
- 在CentOS7中安装思维脑图软件XMind
- archlinux 使用vnc登陆 raspberrypi2
- Linux 下 NFS 服务器的安装与配置
- Linux x86 Program Start Up
- 阶 段 习 题 集 (三)
- RHCE7 管理I-12归档文件并在Linux系统间复制文件
- linux 常用性能监控工具备忘
- Linux学习 -- 常用命令
- CentOS下Samba服务器的配置
- Linux基础学习2
- linux git branch 与 git format-patch的用法
- Linux鸟哥私房菜学习笔记(二)
- Linux系统初识--系统简介以及常用命令