当前位置: 首页 > news >正文

DLL的Export和Import

DLL export 是指将 DLL 中的函数和数据输出到其它程式中,以供其使用。 DLL import 是指使用 DLL 的程式引入 DLL 中的函数和数据。
DLL export
DLL 中包含有一个表,称为 export table (以下简称 ET ),其中包含了 DLL 中可以被外部程式使用的所有函数和数据的名字。只有记录在 ET 中的函数和数据才可以被外部程式所使用(如果没有 .DEF 文件的话),其它所有没有记录在 ET 中的函数和数据都被视为是 DLL 私有的。因此,要将 DLL 中的函数和数据 export 只有两个方法:
l DLL 创建一个 .DEF 文件(模块定义文件),并在 build DLL 时使用这个 .DEF 文件。使用这种方法使你可以将函数按序号 export
l DLL 中想要 export 的函数和数据定义前添加 _declspec dllexport )关键字(对于函数和变量定义,加在最前面;对于 class 定义,加在 class 关键字后),这样该函数和数据就会被添加到 ET 中。使用这种方法函数将按名字 export
WINDOWS 下,无论使用上述的哪一种方法,都必须要将 export 函数声明为 _stdcall
关于 C C++ 的兼容问题
如果要写 C C++ 兼容的 DLL ,因为在 C C++ 下使用了不同的名字修饰规则以及不同的调用约定,所以,如果 DLL 是用 C 编写和编译的,则在用于 C++ 模块时,函数的声明前应加上 extern “C” 关键字,以告诉 LINKER 使用 C 外部连接(即按照 C 名字修饰规则在外部模块中寻找函数);反之,如果 DLL 是用 C++ 编写和编译的,则在用于 C 模块时,函数的声明前要加上 extern “C++” 关键字。 VC++ 通过 _cplusplus 宏来标识 C++ 程式。如果是 C++ 程式, VC 编译器就会为你定义 _cplusplus 宏。所以在 DLL 中可以使用如下的技术来解决兼容问题:
#ifdef _cplusplus
extern “C” {
#endif
// 将所有的函数声明放在这里
#ifdef _cplusplus
}
#endif
.DEF 文件
.DEF 文件是包含了 DLL 模块信息的文本文件。其语法结构如下:
LIBRARY DLL file name
DESCRIPTION “descriptions”
EXPORTS
Function names @nums
LIBRARY 为关键字,后面紧跟关联的 DLL 文件名; DESCRIPTION 后为可选的描述字符串,除了增加可读性外没什么用处; EXPORTS 后是 export 函数的列表,首先是函数名,然后是 @ 符号,后紧跟一十进制数,为该函数的标号,范围从 1 DLL export 函数的总数。注意,这里的名字是经过名字修饰后的函数名字,如果是 DLL 是用 C++ 写的话,那么就很郁闷了。
如果是扩展 DLL extension DLL ),并且通过 .DEF 文件 export ,那么必须在头文件中添加如下的语句:
 #undef AFX_DATA
 #define AFX_DATA AFX_EXT_DATA
 // 头文件中的其它内容
 #undef AFX_DATA
 #define AFX_DATA
这些语句确保一些 MFC 中内部使用的变量被 export 到外部程式中。例如:在 class 中通过 DECLARE_DYNAMIC 获得的 CRuntimeClass 变量。否则 DLL 将会无法正确地编译和连接,或外部程式无法正确连接到该 DLL
DLL import
外部程式的一个源文件要使用 DLL 中的函数和数据,就像要使用外部模块中的函数和数据一样,必须首先给出函数和数据的声明;对于 class 则要给出类的定义。这就称为 import 。对于 VC 编译器, Import DLL 的函数和数据的语法与一般的声明类似,但要在前面加上 _declspec dllimport )关键字(对于函数和变量声明,加在最前面;对于 class 定义,加在 class 关键字后)。如果是函数,则该关键字是可选的,但使用该关键字有可能会导致编译器产生较高效的代码。但对于变量和 class ,则必须使用该关键字。
通过使用以下的技术,可以编写在 .LIB 文件和外部程序源文件通用的头文件:
 #ifdef _EXPORTING
 #define CLASS_DECLSPEC __declspec(dllexport)
 #else
  #define CLASS_DECLSPEC __declspec(dllimport)
 #endif
编译器提供的 _EXPORTING 宏可以用于标式该源文件来自 DLL 文件还是外部程式。

相关文章:

  • 双向链表删除节点时间复杂度_leetcode 19 删除链表的倒数第N个节点(c++)
  • Struts、spring、hibernate、EJB、ant术语说明
  • nexus 安装_Nexus在windows和centos中安装教程
  • 傅里叶级数拟合实验
  • k8s 安装nfs_GCP学习笔记6-NFS\MySQL\GKE配置
  • 数据图表与分析图_单一数据图表动态展示,学会圆环图搭配饼图,效果就是与众不同...
  • 关于inline函数
  • python怎么重新运行_崩溃后如何重新运行Linux? - python
  • 蓝眼泪
  • python3元组_python3 列表、元组操作
  • AT91RM9200引导程序的建立(一)--------建立交叉编译工具链
  • python 平均值_Python随笔11:Python代码规范之注释和文档
  • 心中无敌,天下无敌——转“赢在中国”主持人王利芬的博客片断
  • qt qmidarea 关闭事件_Qt摄像头热插拔实现
  • ogm 转 avi
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • canvas 绘制双线技巧
  • echarts的各种常用效果展示
  • Git的一些常用操作
  • Java|序列化异常StreamCorruptedException的解决方法
  • Javascript设计模式学习之Observer(观察者)模式
  • Java编程基础24——递归练习
  • JS实现简单的MVC模式开发小游戏
  • JS专题之继承
  • Laravel核心解读--Facades
  • MaxCompute访问TableStore(OTS) 数据
  • mongo索引构建
  • React+TypeScript入门
  • SpingCloudBus整合RabbitMQ
  • 工作手记之html2canvas使用概述
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 少走弯路,给Java 1~5 年程序员的建议
  • 实现菜单下拉伸展折叠效果demo
  • 思考 CSS 架构
  • 听说你叫Java(二)–Servlet请求
  • 详解移动APP与web APP的区别
  • 想使用 MongoDB ,你应该了解这8个方面!
  • k8s使用glusterfs实现动态持久化存储
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • #### go map 底层结构 ####
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #微信小程序:微信小程序常见的配置传值
  • (搬运以学习)flask 上下文的实现
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (黑马C++)L06 重载与继承
  • (九)信息融合方式简介
  • (一)为什么要选择C++
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • *Django中的Ajax 纯js的书写样式1
  • ../depcomp: line 571: exec: g++: not found
  • .Net Core 中间件验签