【转】采用dlopen、dlsym、dlclose加载动态链接库【总结】

1、前言

  为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。linux提供了加载和处理动态链接库的系统调用,非常方便。本文先从使用上进行总结,涉及到基本的操作方法,关于动态链接库的本质及如何加载进来,需要进一步学习,后续继续补充。如何将程序设计为插件形式,挖掘出主题和业务之间的关系,需要进一步去学习。

2、生产动态链接库

编译参数 gcc -fPIC -shared 

例如将如下程序编译为动态链接库libcaculate.so,程序如下:

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 -fPIC -shared caculate.c -o libcaculate.so 

3、dlopen、dlsym函数介绍

在linux上man dlopen可以看到使用说明,函数声明如下:

#include <dlfcn.h>

void *dlopen(const char *filename, int flag);

char *dlerror(void);

void *dlsym(void *handle, const char *symbol);

int dlclose(void *handle);

  dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,dlerror返回出现的错误,dlsym通过句柄和连接符名称获取函数名或者变量名,dlclose来卸载打开的库。 dlopen打开模式如下:

  RTLD_LAZY 暂缓决定,等有需要时再解出符号 
  RTLD_NOW 立即决定,返回前解除所有未决定的符号。

采用上面生成的libcaculate.so,写个测试程序如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <dlfcn.h>
 4
 5 //动态链接库路径
 6 #define LIB_CACULATE_PATH "./libcaculate.so"
 7
 8 //函数指针
 9 typedef int (*CAC_FUNC)(int, int);
10
11 int main()
12 {
13     void *handle;
14     char *error;
15     CAC_FUNC cac_func = NULL;
16
17     //打开动态链接库
18     handle = dlopen(LIB_CACULATE_PATH, RTLD_LAZY);
19     if (!handle) {
20     fprintf(stderr, "%s\n", dlerror());
21     exit(EXIT_FAILURE);
22     }
23
24     //清除之前存在的错误
25     dlerror();
26
27     //获取一个函数
28     *(void **) (&cac_func) = dlsym(handle, "add");
29     if ((error = dlerror()) != NULL)  {
30     fprintf(stderr, "%s\n", error);
31     exit(EXIT_FAILURE);
32     }
33     printf("add: %d\n", (*cac_func)(2,7));
34
35     cac_func = (CAC_FUNC)dlsym(handle, "sub");
36     printf("sub: %d\n", cac_func(9,2));
37
38     cac_func = (CAC_FUNC)dlsym(handle, "mul");
39     printf("mul: %d\n", cac_func(3,2));
40
41     cac_func = (CAC_FUNC)dlsym(handle, "div");
42     printf("div: %d\n", cac_func(8,2));
43
44     //关闭动态链接库
45     dlclose(handle);
46     exit(EXIT_SUCCESS);
47 }

编译选项如下:gcc -rdynamic -o main main.c -ldl

测试结果如下所示:

参考资料:

http://blog.chinaunix.net/uid-26285146-id-3262288.html

http://www.360doc.com/content/10/1213/22/4947005_77867631.shtml

原文地址:https://www.cnblogs.com/xiangcaizhen/p/8726935.html

时间: 2024-10-08 23:00:11

【转】采用dlopen、dlsym、dlclose加载动态链接库【总结】的相关文章

(十二)插件之dlopen/dlsym/dlclose 加载动态链接库

dlopen, dlsym, dlclose 加载动态链接库 参考: 采用dlopen.dlsym.dlclose加载动态链接库[总结] linux动态库加载的秘密 三种思路:解决动态库版本兼容 1. 插件 插件(Plug-in 又译外挂)是一种遵循一定规范的应用程序接口编写出来的程序. 应用软件提供使插件能够应用的各项服务,其中包括提供加载方式,使插件可以加载到应用程序和网络传输协议中,从而和插件进行数据交换. 插件必须依赖于应用程序才能发挥自身功能,仅靠插件是无法正常运行的.相反地,应用程序

采用dlopen、dlsym、dlclose加载动态链接库【总结】

摘自http://www.cnblogs.com/Anker/p/3746802.html 采用dlopen.dlsym.dlclose加载动态链接库[总结] 1.前言 为了使程序方便扩展,具备通用性,可以采用插件形式.采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件.linux提供了加载和处理动态链接库的系统调用,非常方便.本文先从使用上进行总结,涉及到基本的操作方法,关于动态链接库的本质及如何加载进来,需要进一步学习,后续继续补充.如何将程序设

加载动态链接库——dlopen dlsym dlclose

DLOPEN?DLMOPEN?DLCLOSE NAME ????dlclose, dlopen, dlmopen - 打开/关闭共享对象 SYNOPSIS #include <dlfcn.h> void *dlopen(const char *filename, int flags); int dlclose(void *handle); #define _GNU_SOURCE #include <dlfcn.h> void *dlmopen (Lmid_t lmid, const

React-Native系列Android——SoLoader加载动态链接库

SoLoader是facebook出品的一款小巧的用于加载so库文件的开源项目,主要作用是自动检查和加载多个有依赖关系的so库文件.在Android平台下React-Native项目大量使用了动态链接库,即JNI技术,作为Java和Javascript两种程序语言之间的通信桥梁. 解压一个React-Native项目的安装包apk文件,我们可以看到一共有15个so库文件,其中libreactnativejni.so是JNI桥梁的入口. 而libreactnativejni.so又依赖于以下12个

为什么JVM的类加载要采用双亲委派的加载机制?

为什么JVM要采用双亲委派机制加载类呢? 任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间. 也就是说,判断2个类是否“相等”,只有在这2个类是由同一个类加载器加载的前提下才有意义,否则即使这2个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,这2个类必定不相等. 基于双亲委派模型设计,那么Java中基础的类,Object类似Object类重复多次的问题就不会存在了,因为经过层层传递,加

LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror(转)

dlopen 基本定义 功能:打开一个动态链接库  包含头文件:  #include <dlfcn.h>  函数定义:  void * dlopen( const char * pathname, int mode );  函数描述:  在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程.使用dlclose()来卸载打开的库.  mode:分为这两种  RTLD_LAZY 暂缓决定,等有需要时再解出符号  RTLD_NOW 立即决定,返回前解除所有未决定的符号

C语言从代码中加载动态链接库

动态加载库需要用到的函数 函数:void *dlopen(const char *filename, int flag); 功能:打开动态链接库文件 参数:filename 动态链接库文件名 flag 打开方式,一般为RTLD_LASY 返回值:库指针 函数:char *dlerror(void); 功能:获取错误值 返回值:错误值 函数:void *dlsym(void *handle, const char *symbol); 功能:获取动态链接库中指定函数的指针 参数:handle 库指针

MFC加载动态链接库方法

1.LoadDll.cpp 1 #include "StdAfx.h" 2 #include "LoadDLL.h" 3 4 pMFCCallBackDll DLL_MFCCallBackDll; 5 6 HINSTANCE g_Hinstance; //实例句柄 7 8 //加载DLL 9 BOOL LoadDll(char *name) 10 { 11 //char name[200] = {""}; //DLL名字存放,且,最大长度为50

隐式加载动态链接库注意事项

在新建的Dll工程中,创建继承子类,其父类是另一Dll工程中的函数.此时,需将父类所在Dll工程的Lib文件加载到当前工程中,可能遇到的问题如下: 1.未将相关的头文件加到工程中,将导致加载的DLL没有相关函数的声明 2.编译时提示“can not open "***.lib" file”,是因为加载lib 库文件的路径没有设置正确,在,Project--Settings--Link--Category(Input选项)下的--Addtional Library Path中设置LIB文