总结下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函数方式->导出类方式。

C++中模块(Dll)对外暴露接口的方式的更多相关文章

  1. sdk开发时,对外暴露的接口封装

    思考,用同步还是异步? 实质就是屏蔽一些东西,让使用者直接传参数 拿结果 而不用关心具体实现 eg.登陆接口 1.定义接口LoginCallBack,两个函数 请求成功和失败 public inter ...

  2. php在apache中一共有三种工作方式:CGI模式、FastCGI模式、Apache 模块DLL

    php在apache中一共有三种工作方式:CGI模式.FastCGI .FastCGI是什么? FastCGI是语言无关的.可伸缩架构的CGI开放扩展,其主要行 为是将CGI解释器进程保持在内存中并因 ...

  3. WPF内嵌WCF服务对外提供接口

    要测试本帖子代码请记得管理员权限运行vs. 我写这个帖子的初衷是在我做surface小车的时候有类似的需求,感觉这个功能还挺有意思的,所以就分享给大家,网上有很多关于wcf的文章 我就不一一列举了.公 ...

  4. 在C++中调用DLL中的函数 (3)

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  5. Delphi 中的DLL 封装和调用对象技术(刘艺,有截图)

    Delphi 中的DLL 封装和调用对象技术本文刊登2003 年10 月份出版的Dr.Dobb's 软件研发第3 期刘 艺摘 要DLL 是一种应用最为广泛的动态链接技术但是由于在DLL 中封装和调用对 ...

  6. JavaScript中模块“写法”

    在JavaScript模块到底是什么 event = function() { // do more return { bind: function() {}, unbind: function() ...

  7. [转载]解析WINDOWS中的DLL文件---经典DLL解读

    [转载]解析WINDOWS中的DLL文件---经典DLL解读 在Windows世界中,有无数块活动的大陆,它们都有一个共同的名字——动态链接库.现在就走进这些神奇的活动大陆,找出它们隐藏已久的秘密吧! ...

  8. springboot+CXF开发webservice对外提供接口(转)

    文章来源:http://www.leftso.com/blog/144.html 1.项目要对外提供接口,用webservcie的方式实现 2.添加的jar包 maven: <dependenc ...

  9. 在后台业务管理系统中使用Autofac实现微信接口的处理

    在后台业务管理系统中使用Autofac实现微信接口的处理,我们只需要把相关使用到的DLL放到BIN目录里面即可,通过IOC控制反转方式实现对接口的调用.在实现在业务系统里面,我们本身程序可能已经依赖了 ...

随机推荐

  1. Xshell 找到上次执行的命令

    ctrl + p   返回上一次输入命令字符 ctrl + r       输入单词搜索历史命令

  2. Django视图之ORM数据库查询操作API

    查询表记录 查询相关API 操作:models.表名.objects.方法() all(): 查询所有结果 filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 get(**kwar ...

  3. 《java并发编程实战》读书笔记1--线程安全性,内置锁,重入,状态

    什么是线程安全? 当多个线程访问某个类时,不管这些的线程的执行顺序如何,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的. 哈哈书上的解释,还是翻译过 ...

  4. window下线程同步之(Critical Sections(关键代码段、关键区域、临界区域)

    关键区域(CriticalSection) 临界区是为了确保同一个代码片段在同一时间只能被一个线程访问,与原子锁不同的是临界区是多条指令的锁定,而原子锁仅仅对单条操作指令有效;临界区和原子锁只能控制同 ...

  5. shadownsocks SSR 账号密码注册 可1元体验一天

    shadownsocks SSR 账号密码注册 可1元体验一天 注册地址 https://www.cup123.club/register?aff=809

  6. 5.Spark Streaming流计算框架的运行流程源码分析2

    1 spark streaming 程序代码实例 代码如下: object OnlineTheTop3ItemForEachCategory2DB { def main(args: Array[Str ...

  7. 将对象转换为JSON字符串

    将对象转换为JSON串: 方案一: 可以通过json-lib工具jar包进行转化:在www.json.org官网下载jar包. 方案二: 通过ObjectMapper对象进行转换 需要引入相应的jar ...

  8. VS2015运行 cordova 时候提示无法运行解决

    出现此问题的原因是在于npm程序损坏了.vs调用的npm程序并不是在node安装目录下的npm,而是在: C:\Users\用户名\AppData\Roaming\Microsoft\VisualSt ...

  9. 其实参与QtCreator开发也很容易

    http://bbs.csdn.net/topics/370241186 10个月前发过一个组建Qt团队,共同研究.学习.完善QtCreator的帖子,不过在为QtCreator提交完一个补丁后,就没 ...

  10. 安装 gcc 编译器

    1.安装编译工具 gcc.gcc-c++.make 注意解决依赖关系,推荐使用 yum 安装,若不能联网可使用安装光 盘做为 yum 源 1)编辑 yum 配置文件: Mount /dev/cdrom ...