当前位置: 首页 > 编程日记 > 正文

C++中模块(Dll)对外暴露接口的方式

总结下C++中模块(Dll)对外暴露接口的方式:

(1)导出API函数的方式
这种方式是Windows中调用DLL接口的最基本方式,GDI32.dll, User32.dll都是用这种方式对外暴露系统API的。
这种方式的优点是导出函数没有语言限制,什么语言都能调用;
缺点是这种方式是面向过程的,外部如果要支持多实例等不是很方便,另外它要求的回调函数(callback)只能是普通C函数,C++中我们通常用类静态成员函数,很不方便。
当然,我们通过封装其实也可以让这种方式支持多实例,通过一个抽象句柄HComponent, 比如支持导出函数HComponent CreateInstance(); VOID DeleteInstance(HComponent h);然后内部的其他导出函数的第一个参数都是实例句柄,类似INT SendMessage(HComponent h, ...), 用这种方式可以模拟出面向对象的效果。
另外如果用动态加载(LoadLibrary, GetProcAddress)的方式调用它的导出函数,即使导出函数内部实现修改了,外部程序也不用重新编译,仍然可用。
导出函数方式一个比较优秀的例子是GDI+的实现,整个GdiPlus.dll对外提供的都是普通导出函数,但是它却可以方便的给面向对象的语言使用,因为一方面它用Handle的方式在DLL内部封装了对象,另一方面它在DLL外围又用C++类的方式封装了头文件直接提供给用户, 所以C++程序可以直接以面向对象的方式调用。

(2)导出类方式
导出类的方式就是把整个C++类对外导出, MFC42.dll就是这种方式。
这种方式的优点是直接面向对象。
缺点是只能给C++用,而且最好编译器都要一致,另外DLL一变动, 外部程序需要重新编译, 而且外部程序可以通过头文件看到你类的内部实现,
所以这种方式是最不建议使用的方式。

(3)COM方式
COM方式实际上导出了几个固定函数(DllGetClassObject, DllCanUnloadNow, DllRegisterServer, DllUnregisterServer), 然后以这几个函数为入口,调用组件内部‘实现的接口。
COM方式综合了上面2种方法的所有优点,没有语言限制,面向对象,多实例,只能看到接口,动态升级等。
当然COM因为其复杂性和对注册表的依赖,很多时候我们在封装模块时不愿意严格按照COM标准来实现,但是我们可以按照COM思想来提供接口。
比如我们可以让我们模块只提供一个导出函数CreateFactory, 然后外部可以调用该接口来创建工厂,最后通过工厂创建出各种类型的对象,这些对象实现了某些接口,外部只需要这些接口的头文件即可调用对象的方法。
现在越来越多的组件以这种方式对外提供接口,比如D2D对外的导出接口就是D2D1CreateFactory, 然后就可以通过该工厂来创建其他的对象,比如pD2DFactory->CreateHwndRenderTarget(...),最后可以直接调用对象实现的接口:pRenderTarget->DrawRectangle(D2D1::RectF(100.f, 100.f, 500.f, 500.f), pBlackBrush);

当然,上面几种DLL对外暴露接口的方式本质上没有区别,都是利用PE文件的导出节来导出数据和函数,但是根据它们使用方式的不同,对外部模块来说还是有很大的区别,我们的推荐次序依次是:COM方式->导出API函数方式->导出类方式。

转载于:https://www.cnblogs.com/h2zZhou/p/5306695.html

相关文章:

LVS详解及基于LVS实现web服务器负载均衡

前言LVS(Linux Virtual Server)Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。通过LVS提供的负载均衡技术和Linux操作系统可实现一个高性能、高可用的服务器群集,从…

解决Ubuntu系统下git clone下载速度较慢的问题(亲测有效)

常见问题使用Git clone下载网速通常有十几kb,下载较慢. 使用以下指令即可解决: //这是我们要clone的,通常是github.com需要替换掉,就是在github.com后面加上.cnpmjs.org就可以了 git clone https://github.com/Hacker…

Revit结构2021专业人士的选择:从入门到专业

Revit结构2021专业人士的选择:从入门到专业 Revit Structure 2021 : 13th Floor Concrete Building 你会学到: Revit结构中的第13栋混凝土建筑 在Revit结构中启动新项目 创建级别的基本方法 创建关卡的技巧 在Revit结构2021中处理主要和次要问题 网格的绘制 直线和曲线网格 圆…

神奇的FireFox

今天开发的时候用FireFox,然后有个js总是不出效果,window.close,然后换个浏览器就完全没问题了,还有onkeydown->ruturn false 屏蔽按键,FireFox也不行........ 果然FireFox这么好用是有原因的... 推荐大家开发的时候还是用360极速,自用还是FireFox好一点.转载于:https://www…

python输出结果空格分割_python 输出列表元素实例(以空格/逗号为分隔符)

给定list,如何以空格/逗号等符号以分隔符输出呢? 一般的,简单的for循环可以打印出list的内容: l[1,2,3,4] for i in l: print(i) 输出结果一行一个元素: 1 2 3 4 若想得到以空格或逗号为分隔符的输出结果,代码可改为&a…

My deep learning reading list

My deep learning reading list 主要是顺着Bengio的PAMI review的文章找出来的。包括几本综述文章,将近100篇论文,各位山头们的Presentation。全部都可以在google上找到。BTW:由于我对视觉尤其是检测识别比较感兴趣,所以关于DL的应…

QT串口调试软件

QT串口调试软件软件主界面设置界面关于我们使用介绍软件主界面 本界面主要包括串口设置部分、数据接收部分、数据发送部分以及软件配置部分构成,软件主界面如图1所示。 在图1软件主界面中,位于左侧部分数据数据连接部分,主要功能是与无人机…

Unity提高工作效率的终极指南

本套课程指南通过关于如何更快、更智能地工作的最新技术,帮助Unity创作者节省时间并提高工作效率 你会学到: Unity的创建者节省了时间,提高了生产力。 关于如何更快地使用程序员和艺术家工具集的技巧,无论是个人还是团队。 Unity应该是一种快…

deepin tim(wine)无法安装_利用HyperV虚拟机,如何在Win10上安装Deepin国产操作系统?深度好文!...

随着老美对华为手机业务的封锁,在PC端的操作系统的未来也逐渐引起了人们的重视,一旦Windows停止向国内供应的话,对国内市场的冲击也是不小的。基于这个原因,国产操作系统也越来越频繁地进入大家的视野。在众多国产操作系统中&…

**使用 Git Hook 实现网站的自动部署

http://www.tuicool.com/articles/3QRB7jU 自动化能解放人类的双手,而且更重要的是,因为按照规定的流程来走,也减少了很多误操作的产生。不知道大家平时都是怎么样更新自己生产环境的代码的,FTP 覆盖旧文件、服务器定时任务去 bui…

Mavlink自定义协议

参照本人博客:博客直达 浏览密码:N414 这里不做描述,详细过程请移步本人博客

UE建筑可视化全局照明学习 Unreal Engine: Global Illumination for Arch. Visualization

虚幻引擎:建筑可视化的全局照明 你会学到: 使用轻量级地理信息引擎 聚焦胃肠计算 生成灯光贴图Uv 轻度烘焙 控制光反弹 使用环境遮挡 动画和地理信息 暴露 保存高分辨率图像 课程获取:UE建筑可视化全局照明学习-云桥网 时长:1h 30m |视频:. MP4,12807…

dbf如何导入oracle_「赵强老师」第一个Oracle的手工管理的备份和恢复

一、什么是手工管理的备份与恢复?尽管在Oracle中,已经有了RMAN的备份与恢复。但是作为Oracle备份恢复的一种方式,我们将在本文中通过一个例子来为大家介绍如何使用手工的方式来完成Oracle的备份与恢复。手工方式的本质是通过操作系统的cp命令…

大小端存储模式的理解和判断

在计算机系统中,存储是以字节为单位的,每个地址单元都对应着一个字节,一个字节8bit。在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器)。对于位数大于8位的处理…

汇编语言学习随笔

1.可执行文件中包含两部分内容: *程序(从源程序中的汇编指令翻译过来的机器码)和数据(源程序中定义的数据) *相关的描述信息(比如程序有多大,占多少内存空间啊等等) 2.segment和ends…

新装Ubuntu18.04系统配置PX4环境

1.安装QGC地面站系统:链接:https://docs.qgroundcontrol.com/master/en/getting_started/download_and_install.html 2.配置系统文件:下载PX4代码 -->打开代码 -->找到文件夹Tools文件 -->找到setup文件夹 -->找到ubuntu.sh文件&…

Blender程序性纹理学习教程大师班 Creative Shrimp – Procedural Texturing Blender Master Class

标题:创意虾-程序纹理Blender大师班 信息: 什么是程序纹理? 程序纹理将简单的数学转换为无限的真实感着色器,具有无限的多样性和分辨率。 超越看起来像一团像素特写的图像纹理,运用程序纹理的力量,清晰的细节和没有重复的模式。 你…

java 全局变量 内存不回收_Java的内存 - 内存回收

这篇承接上一篇 《Java的内存 - 内存模型》,分析内存回收相关的知识点。 垃圾回收包含两个步骤,①标记哪些内存是垃圾 ②回收内存。下面分别说这两个步骤有哪些算法:1. 垃圾标记1.1 引用计数算法没有哪一种 JVM 是使用「引用计数」作为垃圾回…

题目1000:计算a+b

题目描述&#xff1a;求整数a&#xff0c;b的和。 输入&#xff1a;测试案例有多行&#xff0c;每行为a&#xff0c;b的值。 输出&#xff1a;输出多行&#xff0c;对应ab的结果。 样例输入&#xff1a;1 2 4 5 6 9 样例输出&#xff1a;3 9 15 #include<iostream> using…

Mac下chrome的webapp hostadmin 快速切换host

首先是安装 app &#xff0c;https://chrome.google.com/webstore/detail/hostadmin-app/mfoaclfeiefiehgaojbmncmefhdnikeg Chrome把扩展的NPAPI 禁用了&#xff0c;所以做成APP没以前方便了&#xff0c;但是有总比没有好。 安装之后发现mac下选择host文件没法选&#xff0c;因…

PX4如何开启本地在环仿真?如何将仿真地点定位为本地位置?你进来就对了!

视频预览&#xff1a;3架无人机在环仿真 3架仿真jmavsim本地坐标启动教程 1.首先执行仿真命令 n414414:~/001/Firmware$ make px4_sitl_default jmavsim出现左边界面就说明该仿真是可以进行仿真的&#xff01;由于我在自己写的代码里面启动&#xff0c;所以出现右边提示&…

Blender从头到尾创建低多边形角色学习教程 Low Poly Characters – Blender Bitesize Course

从头到尾创建低多边形角色。 你会学到: Blender界面的基础。 基本建模技术。 如何遵循字符引用&#xff1f; 如何创造和塑造自己的角色(不同风格、发型和服装)。 纹理字符。 索具和动画介绍(用于你的游戏引擎或动画)。 调整您下载的资产包角色&#xff0c;以创建新的不同角色。…

20145101《Java程序设计》第4周学习总结

20145101《Java程序设计》第4周学习总结 教材学习内容总结 第六章 继承与多态 继承&#xff1a;避免多个类间重复定义共同行为。把相同代码提升为父类 运用extends关键字的子类会继承扩充父类行为 多个类中存在相同属性和行为时&#xff0c;将这些内容抽取到单独一个类中&#…

反编译使用yield关键字的方法

我认为这是一个真命题&#xff1a;“没有用.NET Reflector反编译并阅读过代码的程序员不是专业的.NET程序员”。.NET Reflector强大的地方就在于可以把IL代码反编译成可读性颇高的高级语言代码&#xff0c;并且能够支持相当多的“模式”&#xff0c;根据这些模式它可以在一定程…

Android studio 启动自学模式

今天在网上看到了编译Android的软件Android studio&#xff0c;出于对Android的学习兴趣&#xff0c;我打算开始新一轮的Android的学习。今天就是在网上&#xff0c;以及图书馆里查找了有关Android studio的书籍&#xff0c;但是由于Android是在13年才开始发布的原因吧&#x…

AutoCAD 2D与3D大师班学习教程 AutoCAD 2D and 3D Masterclass

用实例和解决问题的方法完成从基础到专业的AutoCAD课程。 你会学到什么 AutoCAD课程包含创建计划和模型的命令和不同方法的详细使用。 本课程包括对AutoCAD中使用的所有命令和工具的详细解释。 课程内容是按时间顺序设计的&#xff0c;以了解承担项目的实际方法。 本课程包含两…

威纶通宏开机后使用初始化宏指令_【操作系统】我们按下电脑开机键的背后发生了什么?...

作者&#xff1a;CVNot链接&#xff1a;https://juejin.im/post/5e8844996fb9a03c6675b9d6操作系统是什么&#xff1f;操作系统是用来管理计算机硬件的软件&#xff0c;狭义上实现该定义的为操作系统内核&#xff1b;而更加宽泛的操作系统概念为根据内核对外提供了一些OS服务&a…

Linux常用压缩与解压缩命令

.tar 解包&#xff1a;tar xvf FileName.tar打包&#xff1a;tar cvf FileName.tar DirName&#xff08;注&#xff1a;tar是打包&#xff0c;不是压缩&#xff01;&#xff09;———————————————.gz解压1&#xff1a;gunzip FileName.gz解压2&#xff1a;gzip -d…

【Kubernetes】如何使用Kubeadm部署K8S集群

一 . 准备机器 本次环境采用华为云ECS弹性云服务器部署&#xff08;也可以使用VMware&#xff09; vm01&#xff08;2V4G&#xff09;&#xff1a; Ubuntu_18.04作为K8S master节点 vm02&#xff08;1V1G&#xff09;&#xff1a; Ubuntu_18.04作为K8S node节点 备注: 以下所有…

解决ORA-28000: the account is locked

在oracle中&#xff0c;连续十次尝试登陆不成功&#xff0c;那么此账户将会被锁定&#xff08;lock&#xff09;。当使用被锁定的账户登录时&#xff0c;系统会报错&#xff1a;ORA-28000: the account is locked。查询FAILED_LOGIN_ATTEMPTS参数默认值&#xff0c;这个参数限制…