Linux编程中链接库的使用
动态链接库:程序运行过程中,动态加载进内存的库(动态库加载需要资源消耗,但可以显著降低可执行文件体积)
1、大型软件项目中,不同模块可以各自完成,然后封装成链接库供上层模块调用。
2、一些通用的功能,如文件处理、数据库接口、算法等,可以封装成库,从而避免每个模块都维护一份独立的通用代码。
3、项目中有很多小的业务模块,可以把各模块制作成统一接口的动态库,主进程根据实际业务按需加载。
一是在主程序里需有静态库接口函数的声明,一般使用一个头文件;
二是在编译时加载静态库,如linux gcc编译时可以用形如-lcpplib的选项来加载一个文件名为libcpplib.a或libcpplib.so的库。
这里说明下命名规范,一般建议静态库的后缀用.a,动态库后缀用.so。
满足上面两点,静态库里的函数就可以像平常一样直接使用了。
这里抛个问题,既然是动态加载的,主程序怎么知道里面有什么函数,怎么调用呢?
在linux系统里,可以nm查看链接库的符号表,也即是里面的函数表。Linux程序的动态库调用,也提供了4个加载动态库相关的函数:dlopen、dlsym、dlerror和dlcolose。
#include <dlfcn.h>/*包含的头文件*/
/*pathname为动态库文件名;mode是打开方式,如RTLD_NOW表示直接解析出动态库中所有的符号*/
/*此函数返回一个void指针指向加载的库的句柄*/
void * dlopen( const char * pathname, int mode);
/*handle为dlopen返回的句柄,symbol为函数名*/
/*此函数返回库里指定名称的函数的指针*/
void*dlsym(void*handle,constchar*symbol);
/*此函数在加载链接库出错时,返回错误信息*/
char *dlerror(void);
/*关闭指定的动态库句柄*/
int dlclose (void *handle);
该段代码实现一个动态库调用接口DllRun,通过向该接口传递业务数据、库名、函数名,可以指定相应的库函数来处理数据。
同时iFlag控制该动态库在使用完后是否立即释放,如果不释放(频繁使用的库不释放可以节省加载的开支),则将库句柄指针压入MAP。
#include <dlfcn.h>
map<const char*, dll_func> mapFunc;/*保存不释放的动态库*/
函数功能:加载动态库并执行相应的业务函数
输入参数:strData - 业务数据,根据实现业务情况选择用什么方式传递业务数据,比如数据多且可以按字段划分,可以用map
strDllName - 需要加载的库名称
strFunc - 业务的函数名称
iFlag - 加载方式:
0 - 第1次加载后Handle保存到map,之后调用不重新加载
1 - 每次加载均释放掉,下次重新加载
输出参数:strData - 函数执行后输出数据
返回值:0 - 成功;其他失败
*/
int DllRun(char* strData, const char* strDllName, const char* strFunc, int iFlag)
{
int iRet=-1;
dll_func pFunc=NULL;/*业务函数的指针*/
void* pHandle=NULL;
if(NULL == strFunc)
{
iRet = -1;
goto DllRun_RETURN;
}
if(!iFlag)
{
pHandle = mapFunc[strDllName];
}
if(NULL == pHandle)
{ /*加载动态库*/
pHandle = dlopen(strDllName, RTLD_NOW);
if(NULL == pHandle)
{
printf("加载链接库[%s]失败: %s\n", strDllName, dlerror());
iRet = -2;
goto DllRun_RETURN;
}
}
func = dlsym(pHandle, strFunc);/*获取业务函数指针*/
if(NULL == func)
{
printf("获取动态库[%s]的函数[%s]的指针失败: %s\n", strDllName, strFunc, dlerror());
iRet = -3;
goto DllRun_RETURN;
}
iRet = func(strData);/*业务执行*/
if(0 != iRet)
{
goto DllRun_RETURN;
}
if(iFlag)
{
if(NULL != pHandle)
{
dlclose(pHandle);
}
}
else
{
mapFunc[strDllName] = pHandle;
}
return iRet;
}
Linux编程中链接库的使用的更多相关文章
- linux下静态链接库的用法
最近在Linux下编程发现一个诡异的现象,就是在链接一个静态库的时候总是报错,类似下面这样的错误: (.text+0x13): undefined reference to `func' 关于unde ...
- Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名
Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名 转载自:http://b ...
- Linux 编程中的API函数和系统调用的关系【转】
转自:http://blog.chinaunix.net/uid-25968088-id-3426027.html 原文地址:Linux 编程中的API函数和系统调用的关系 作者:up哥小号 API: ...
- linux c静态链接库与动态链接库
库函数是我们编程的时候经常用到的,我们协作编程的时候可以将常用的函数封装成库供大家使用,这样能够提高大家的工作效率.对于库函数,它分为动态链接库和静态链接库.对于静态链接库我们必须是连接到可执行文件中 ...
- Linux系统中“动态库”和“静态库”那点事儿【转】
转自:http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻. ...
- Linux系统中“动态库”和“静态库”那点事儿
摘自http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻.在 ...
- linux下静态链接库和动态链接库
关于链接库的知识,网上太多资料了,但是并不代表我很熟悉.今天遇到了 一个问题,就是由于静态链接库和ubuntu系统不兼容导致的,虽然花了点时间才搞定 但是,其中暴露的问题也不少. 没有区分好静态链接库 ...
- Linux下 静态链接库 和 动态链接库
先来说说C/C++编译过程 编译: 检查语句符号定义,将C/C++代码翻译生成中间语言. 链接: 将中间代码整合,生成可执行的二进制代码. 简单的说,库文件都是一种特殊的中间语言文件,静态库还是一种特 ...
- Linux编程中的坑——C++中exit和return的区别
今天遇到一个坑,折腾了一天才把这个坑填上,情况是这样的: 写了段代码,在main()函数中创建一个分离线程,结果这个线程什么都没干就直接挂掉了,代码长这样: int main() { 创建一个分离线程 ...
随机推荐
- iOS VIPER架构(三)
路由是实现模块间解耦的一个有效工具.如果要进行组件化开发,路由是必不可少的一部分.目前iOS上绝大部分的路由工具都是基于URL匹配的,优缺点都很明显.这篇文章里将会给出一个更加原生和安全的设计,这个设 ...
- ios 根据字典自动生成属性
- (void)createPropertyCode{ NSMutableString *codes = [NSMutableString string]; // 遍历字典 [self enumera ...
- SqlServer中生成一串连续数字
在SQLServer中一串连续数字,如1,2,3,4,5,....或者 1 2 3 4 5 没有现成方法,网上都用通用表表达式递归生成.今天想到一个还算简单的方法,记录下来: select row_n ...
- POJ Charm Bracelet 挑饰品 (常规01背包)
问题:去珠宝店抢饰品,给出饰品种数n,能带走的重量m,以及每种饰品的重量w与价值v.求能带走的最大量. 思路:常规01背包. #include <iostream> using names ...
- BZOJ 4491: 我也不知道题目名字是什么 RMQ
4491: 我也不知道题目名字是什么 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 317 Solved: 174[Submit][Status][ ...
- 用GWT开发的HelloGWT程序
GWT项目可以通过 命令行和Eclipse插件两种方法创建.创建GWT项目的命令是webAppCreator,具体使用方法可以看GWT的开发文档. Eclipse插件安装完成后,Eclipse的工具条 ...
- 【UML】时序图Sequence diagram(交互图)(转)
前言 UML时序图是UML动态图之一,它是强调时间顺序的交互图. 定义 时序图是显示按时间顺序排列的对象之间交互的图. 组成元素 对象 包括三种命名 ...
- Android(java)学习笔记114:Service生命周期
1.Service的生命周期 Android中的Service(服务)与Activity不同,它是不能和用户交互,不能自己启动的,运行在后台的程序,如果我们退出应用的时候,Servic ...
- Android(java)学习笔记123:Android MediaPlayer 播放prepareAsync called in state 8解决办法
1. 使用android MediaPlayer播放音频文件时,有时会出现prepareasync called in state 8错误. 以下方法可以避免这个异常出现. 第1种方法: priva ...
- Java(面试题):字符串截取
在Java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符. 但对应的字节数不同,一个汉字占两个字节. 定义一个方法,按照指定的字节数来取子串. 如:对于“ab你好”,如果取三个字 ...