2021SC@SDUSC
6 动态模块加载
6.1 动态库加载

动态库加载函数能让用户在程序中加载所需要的模块,各个平台下的加载函数是不一样的。

动态加载函数一般有如下功能:

1)加载动态库

windows下的函数LoadLibraryA ;
linux 下的函数dlopen ;
这些函数一般需要动态库的名字作为参数。

2)获取函数地址
windows下的函数 GetProcAddress
linux 下的函数 dlsym。
这些函数一般需要函数名作为参数,回函数地址。

3)卸载动态库
windows下的函数 FreeLibrary
linux 下的函数 dlclose。

6.2 DSO概述

DSO 可以让用户动态加载动态库来进行函数调用。

各个平台下加载动态库的函数是不一样的,
openssl的DSO对各个平台台下的动态库加载函数进行了封装,增加了源码的可移植性。
Openssl的DSO功能主要用于动态加载压缩函数(ssl协议)和 engine(硬件加速引擎)。

Openssl的DSO功能除了封装基本的功能外还有其他辅助函数,
主要用于解决不同系统下路径不同的表示方式以及动态库全名不一样的问题。

比如windows系统下路径可以用“\”和“/”表示,而linux下只能使用“/”;
windows下动态库的后缀为 .dll 而 linux 下动态库名字一般为 libxxx.so。

6.3 数据结构

dso数据结定义在crypto/dso/dso.h中,如下所示:

       struct dso_st {DSO_METHOD *meth;STACK *meth_data;int references;int flags;CRYPTO_EX_DATA ex_data;DSO_NAME_CONVERTER_FUNC name_converter;DSO_MERGER_FUNC merger;char *filename;char *loaded_filename;};

meth: 指出了操作系统相关的动态库操作函数。
meth_data:堆栈中存放了加载动态库后的句柄。
references: 引用计数,
DSO_new 时置1,
DSO_up_ref 时加1,
DSO_free 时减1。

当调用DSO_free时,
只有当前的 references 为 1 时
才真正释放meth_data中存放的句柄。
flags: 与加载动态库时加载的文件名以及加载方式有关,用于DSO_ctrl函数。
DSO_convert_filename: 当加载动态库时会调用DSO_convert_filename函数来确定所加载的文件.
而DSO_convert_filename函数会调用各个系统
自己的convert函数来获取这个文件名。
对于flags有三种种操作命令:设置、读取和或的关系,对应定义如下:

               #define DSO_CTRL_GET_FLAGS      1#define DSO_CTRL_SET_FLAGS       2#define DSO_CTRL_OR_FLAGS       3而flags可以设置的值有如下定义:#define DSO_FLAG_NO_NAME_TRANSLATION            0x01#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY      0x02#define DSO_FLAG_UPCASE_SYMBOL                         0x10#define DSO_FLAG_GLOBAL_SYMBOLS                       0x20

意义说明如下:
DSO_FLAG_NO_NAME_TRANSLATION
加载的文件名与指定的文件名一致,不加后缀.dll(windows)或.so(linux或unix)。
DSO_FLAG_NAME_TRANSLATION_EXT_ONLY
加载的文件名会加上lib串,比如用户加载eay32,真正加载时会加载libeay32(适用于linux或unix)。
DSO_FLAG_UPCASE_SYMBOL
适用于OpenVMS。
DSO_FLAG_GLOBAL_SYMBOLS
适用于unix,当在unix下调用加载函数dlopen时,参数会被或上RTLD_GLOBAL。
ex_data:扩展数据,没有使用。
name_converter::指明了具体系统需要调用的名字计算函数。
loaded_filename:指明了加载动态库的全名。

6.4 编程示例
1

//#include <openssl/dso.h>
#include "internal/dso.h"
#include <openssl/bio.h>
#include <stdio.h>int main()
{DSO  *d;void (*f1)();void (*f2)();BIO  *(*BIO_newx)(BIO_METHOD *a);BIO  *(*BIO_freex)(BIO_METHOD *a);BIO  *test;d=DSO_new();//d=DSO_load(d,"libeay32",NULL,0);d=DSO_load(d,"/usr/local/openssl/lib/libcrypto.so",NULL,0);if ( d == NULL ) {perror("not fond libcrypto.so");return 1;}f1 = DSO_bind_func(d,"BIO_new");f2 = DSO_bind_func(d,"BIO_free");BIO_newx = (BIO *(*)(BIO_METHOD *))f1;BIO_freex = (BIO *(*)(BIO_METHOD *))f2;test = BIO_newx(BIO_s_file());BIO_set_fp(test,stdout,BIO_NOCLOSE);BIO_puts(test,"abd\n\n");BIO_freex(test);DSO_free(d);return 0;
}
/*本例动态加载libeay32动态库,获取BIO_new和BIO_free的地址并调用。
*/2//#include <openssl/dso.h>
#include "crypto/dso/dso_locl.h"
#include "internal/dso.h"
#include <openssl/bio.h>
int    main()
{DSO       *d;void       (*f)();BIO        *(*BIO_newx)(BIO_METHOD *a);BIO        *test;char       *load_name;const char *loaded_name;int        flags;d = DSO_new();
#if 0DSO_set_name_converterDSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NO_NAME_TRANSLATION,NULL);DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NAME_TRANSLATION_EXT_ONLY,NULL);DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_GLOBAL_SYMBOLS,NULL);/* 最好写成libeay32而不是libeay32.dll,* 除非前面调用了DSO_ctrl(d,DSO_CTRL_SET_FLAGS,DSO_FLAG_NO_NAME_TRANSLATION,NULL)* 否则它会加载libeay32.dll.dll*/load_name = DSO_merge(d,"libeay32","D:\\zcp\\OpenSSL\\openssl-0.9.8b\\out32dll\\Debug");
#endif//d = DSO_load(d,"libeay32",NULL,0);d = DSO_load(d,"/usr/local/openssl/lib/libcrypto.so",NULL,0);if(d == NULL){printf("err\n");return -1;}//loaded_name = DSO_get_loaded_filename(d);loaded_name = DSO_get_filename(d);if(loaded_name != NULL){printf("loaded file is %s\n",loaded_name);}flags = DSO_flags(d);printf("current falgs is %d\n",flags);DSO_up_ref(d);f = (void (*)())DSO_bind_func(d,"BIO_new");BIO_newx = (BIO *(*)(BIO_METHOD *))f;test = BIO_newx(BIO_s_file());BIO_set_fp(test,stdout,BIO_NOCLOSE);BIO_puts(test,"abd\n\n");BIO_free(test);printf("filename : %s\n",d->filename);printf("loaded_filename : %s\n",d->loaded_filename);//printf("handle in dso number is : %d\n",d->meth_data->num);DSO_free(d);//DSO_free(d);//printf("handle in dso number is : %d\n",d->meth_data->num);return 0;
}
/*
本例主要演示了DSO的控制函数。
*/

2021SC@SDUSC openssl 动态模块加载相关推荐

  1. nginx php动态编译加载模块.

    #Nginx动态编译加载模块步骤 #查看目前Nginx版本及编译模块 #[root@centos7 ~]# /opt/app/lnmp/nginx-1.12.0/sbin/nginx -V #ngin ...

  2. seajs动态加载js原理_seaJS 模块加载过程分析

    先看一个seajs的官方example,  以下以seajs.use('main')为例, 解析加载mod main的过程 //app.html seajs.use("main") ...

  3. nodejs学习巩固笔记-nodejs基础,Node.js 高级编程(核心模块、模块加载机制)

    目录 Nodejs 基础 大前端开发过程中的必备技能 nodejs 的架构 为什么是 Nodejs Nodejs 异步 IO Nodejs 事件驱动架构 全局对象 全局变量之 process 核心模块 ...

  4. FreeSwitch 的初始化及其模块加载过程

    FS 主函数main() Freeswitch的主函数是在文件switch.c中定义的,该文件的260行是整个程序的入口,主函数主要完成的功能是包括,命令行解析,初始化apr库,构建全局内存池,模块加 ...

  5. ES6 模块加载export 、import、export default 、import() 语法与区别,笔记总结

    ES6模块加载export .import.export default .import() 语法与区别 在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种. ...

  6. 模块加载过程代码分析1

    一.概述 模块是作为ELF对象文件存放在文件系统中的,并通过执行insmod程序链接到内核中.对于每个模块,系统都要分配一个包含以下数据结构的内存区. 一个module对象,表示模块名的一个以null ...

  7. 【Android NDK 开发】Android.mk 配置动态库 ( Android Studio 配置动态库 | 动态库加载版本限制 | 本章仅做参考推荐使用 CMake 配置动态库 )

    文章目录 I . Android Studio 中使用 Android.mk 配置动态库 总结 II . 第三方动态库来源 III . 配置 Android.mk 构建脚本路径 IV . 预编译 第三 ...

  8. ES6 系列之模块加载方案

    前言 本篇我们重点介绍以下四种模块加载规范: AMD CMD CommonJS ES6 模块 最后再延伸讲下 Babel 的编译和 webpack 的打包原理. require.js 在了解 AMD ...

  9. seaJS 模块加载过程分析

    先看一个seajs的官方example,  以下以seajs.use('main')为例, 解析加载mod main的过程 //app.html seajs.use("main") ...

最新文章

  1. linux系统 插优盘安装xvidcap,linux下的视频录制软件xvidcap
  2. 13.2System类中的常用方法
  3. 软件定义无线电matlab书,软件定义无线电
  4. python网络编程项目_python网络编程(1):客户端与网络编程简介
  5. 多线程爬虫191023
  6. 深度学习图像超分辨率最新综述:从模型到应用
  7. rsync和inotify实时同步配置 exclude排除多个文件夹
  8. 如何找mysql8.0的rpm安装包_centos7 mysql8.0 RPM软件包方式安装
  9. Mybatis Generator的使用 1
  10. ofdma技术_数字化领航 | Wi-Fi 6 关键技术剖析
  11. NSURLConnect 的简单实用(iOS8淘汰)
  12. 谷歌云盘超大文件快速下载方法
  13. ASP.net 2.0 中 WebResource.axd 管理资源的一些知识点
  14. 【NPDP产品经理】发散思维让你的思维视野更广阔
  15. 武汉坚守第六十一天——运动健康相关联,牛尿神奇为哪般
  16. 看懂英文数据手册、搭建电路
  17. 程序员五一被拉去相亲,结果彻底搞懂了HTTP常用状态码
  18. 【通州建设】地铁S6线更名为21号线!途径通州多站!
  19. 算法总结——大整数乘法
  20. (window10)使用karas生成网络模型,安装组件及无法成功加载plot_model的解决

热门文章

  1. 借鉴于站酷的css总结
  2. 【深度相机系列三】深度相机分类之双目立体视觉法
  3. 图文手把手教程--ESP32 OTA空中升级(阿里云物联网平台)
  4. 基于arduino的光控窗帘_光控窗帘
  5. zookeeper使用zookeeper_export采集指标报错mntr is not executed because it is not in the whitelist.
  6. 【Java基础】前端传一个数组或者集合后台怎么接受(案例详解)
  7. 10分钟讲清int 和 Integer 的区别
  8. int ** 的理解
  9. matlab图像学习笔记
  10. c语言打开一幅tif格式图像,关于Windows Picture Viewer无法打开部分tif格式图像的问题...