1.为什么使用动态链接库?
为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。linux提供了加载和处理动态链接库的系统调用,非常方便。
2.Linux动态链接库的API
Linux提供了一套API来动态装载库。下面列出了这些API:
- dlopen,打开一个库,并为使用该库做些准备。
- dlsym,在打开的库中查找符号的值。
- dlclose,关闭库。
- dlerror,返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。
dlopen
基本定义
功能:打开一个动态链接库
包含头文件:
#include
函数定义:
void * dlopen( const char * pathname, int mode );
函数描述:
在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。
mode:分为这两种
RTLD_LAZY 暂缓决定,等有需要时再解出符号
RTLD_NOW 立即决定,返回前解除所有未决定的符号。
RTLD_LOCAL
RTLD_GLOBAL 允许导出符号
RTLD_GROUP
RTLD_WORLD
返回值:
打开错误返回NULL
成功,返回库引用
编译时候要加入 -ldl (指定dl库)
dlsym()
功能:
根据动态链接库操作句柄与符号,返回符号对应的地址。
包含头文件:
函数定义:
void*dlsym(void* handle,const char* symbol)
函数描述:
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。
handle是由打开后返回的,symbol就是要求获取的函数或的名称。
dlclose()
dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。
上述都是摘抄,总结为链接的时候需要用到dl库,编译的时候需要加上dlfcn.h头文件。才能保证编译不会报错。
3.使用举例
编译动态链接库
gcc -fPIC -shared caculate.c -o libMyCalFunc.so
-
#include <stdio.h>
-
-
int add(int a, int b)
-
{
-
return (a + b);
-
}
-
-
int sub(int a, int b)
-
{
-
return (a - b);
-
}
-
-
int mul(int a, int b)
-
{
-
return (a * b);
-
}
-
-
int div(int a, int b)
-
{
-
return (a / b);
-
}
主函数连接使用:
gcc -rdynamic -o main main.c -ldl
-
#include <stdio.h>
-
#include <string.h>
-
#include <dlfcn.h>
-
-
const char LIB_PATH[50] = "./libMyCal.so";
-
-
typedef int (* pCalFunc)(int, int);
-
void main()
-
{
-
pCalFunc pFunc = NULL;
-
void *handle = NULL;
-
char* error = NULL;
-
-
handle = dlopen(LIB_PATH, RTLD_LAZY);
-
if (handle == NULL)
-
{
-
fprintf(stderr,"%s\n", dlerror());
-
return;
-
}
-
dlerror();
-
-
*(void* *)&pFunc = dlsym(handle, "add");
-
if ((error=dlerror()) != NULL)
-
{
-
fprintf(stderr,"%s\n",error);
-
return ;
-
}
-
-
printf("add: %d\n",(*pFunc)(2,8));
-
dlclose(handle);
-
}
执行结果:
./main
add: 10
阅读(2268) | 评论(0) | 转发(0) |