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() { 创建一个分离线程 ...
随机推荐
- Codeforces Round #376 (Div. 2) F. Video Cards 数学 & 暴力
http://codeforces.com/contest/731/problem/F 注意到一个事实,如果你要找一段区间中(从小到大的),有多少个数是能整除左端点L的,就是[L, R]这样.那么,很 ...
- HDU 1024 A - Max Sum Plus Plus DP + 滚动数组
http://acm.hdu.edu.cn/showproblem.php?pid=1024 刚开始的时候没看懂题目,以为一定要把那n个数字分成m对,然后求m对中和值最大的那对 但是不是,题目说的只是 ...
- SSIS-Dtsx包文件打开时一直验证
把每个项的DelayValidation设置为true. 也可以直接改文件: 把文件里的 <DTS:Property DTS:Name="DelayValidation"&g ...
- 《四 spring源码》spring的事务注解@Transactional 原理分析
先了解什么是注解 注解 Jdk1.5新增新技术,注解.很多框架为了简化代码,都会提供有些注解.可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件. 注解不会也不能影 ...
- ngnix集群产生的问题
还可使用zookeper解决
- Spring 顾问
1.名称匹配方法切入点顾问 接口:ISomeService public interface ISomeService { public void doSome(); public void doSe ...
- Code First 2
在codefirst一中也说了Mapping是实体与数据库的纽带,model通过Mapping映射到数据库,我们可以从数据库的角度来分析?首先是映射到数据库,这个是必须的.数据库里面一般包括表.列.约 ...
- I/O流操做总结(三)
说实话,其实我并不是很喜欢Java这门语言,尽管它很强大,有很多现成的API可以调用 但我总感觉它把简单的事情弄得太过复杂,甚至有时候会让人迷失 弄不清到底是为了写出东西,还是为了语言本身 我学习的第 ...
- 3、HTTP content-type
HTTP content-type Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式.什么编码读取这个文件, ...
- Reset CSS 页面初始化css
CSS 初始化样式(Reset CSS 官网提供): /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: non ...