Windows平台下C 插件系统实现的几个关键技术问题及其解决思路
Windows平台下C++插件系统实现的几个关键技术问题及其解决思路
windows平台c++设计模式框架工具
作者:朱金灿
来源:http://blog.csdn.net/clever101/
根据我的实践,在Windows平台下设计并实现一个C++插件系统,需要解决几个关键技术问题。下面我谈谈需要解决的几个关键技术问题以及我想到的简单的解决思路。由于我主要专注于Windows平台C++程序的开发,这里假设以VS为编译环境,MFC界面库来说明。
1. 主程序和插件的关系问题
插件架构一般可以用下面的图来表示:
(注:此图来自李先静的博客文章:http://blog.csdn.net/absurd/archive/2006/07/04/877063.aspx,略有修改,特向李大侠表示感谢)
一般来说:应用程序框架所完成的功能应为一个软件系统的核心和基础,这些基本功能主要包括一些核心功能,即可为用户使用,也可为插件使用。插件所完成的功能是对应用程序框架功能的扩展与补充,一般插件完成系列化功能,例如:PHOTOSHOP的滤镜插件完成对图形的特殊效果处理,这些功能都有一些共性,可以进行集中管理,并且是可以定义出标准的插件接口。
还有一般更为极端一点:应用程序框架不实现任何具体的功能,只充当一个插件容器。然后由插件实现具体的功能。
2.界面配置问题
界面配置对大家可能不太陌生。在较早的时候我们曾使用ini文件进行界面配置,随着扩展性更强的XML的兴起,使用XML文件进行界面配置逐渐流行起来。
界面配置的实现流程如下:
3.界面和逻辑的结合及消息处理问题
单纯的实现对界面的配置并不能算是一个插件系统,插件系统更重要的是如何实现对消息的处理。首先我们要明确在一个系统我们主要要处理哪些消息。我总结了一下,请大家看下表:
其中一个桌面应用系统主要处理的是菜单消息、工具栏按钮消息、鼠标消息、键盘消息、键盘消息和系统的其它消息和其它控件消息,如ComboBox控件消息和停靠栏消息。在上面六项中前四项又是主要的。下面我简单谈谈菜单消息、工具栏消息、鼠标消息和键盘消息的实现思路。
菜单消息和工具栏消息的处理本质是一样的,就是以ID为标识来寻找命令消息处理函数以及界面更新处理函数。那么用ID和消息处理函数绑定在一起呢?一种办法是使用boost::bind就行绑定,具体参看我以前写的一篇博客:巧用boost库实现字符串映射消息处理函数。
鼠标和键盘消息的响应有三种思路:一种是使用C++的类的虚函数机制,具体是在底层定义一个消息处理对象的基类,在主程序里有一个消息处理对象的基类指针,在插件模块里实现消息处理对象基类的派生类,并定义一个派生类的变量,在适当的时候将将这个派生类变量的指针赋值给主程序的基类指针,然后这个基类指针负责处理所有的鼠标和键盘消息;
第二种思路是使用C++的回调设计模式(关于C++的回调设计模式,这里有一篇很棒的文章:回调设计模式),具体是凡是要响应鼠标和键 盘消息的插件模块在初始化时都要注册回调函数(所谓注册回调函数主要就是把响应鼠标键盘消息的函数指针保存下来),然后在主程序的鼠标键盘的响应函数里把该指针取出来调用;第三种思路是使用windows的Hook机制,大致的思路是在插件模块里使用钩子来截获所有窗口的鼠标键盘消息,这个思路我还没有更多的思考,但我想应该是可以的。
拉拉杂杂谈了一些插件系统实现的思路,希望能对大家能有所帮助。
分享到:
上一篇:warning LNK4070的解决办法
下一篇:以教促学,共享信息
查看评论
12楼 buaasuozi 2012-10-22 17:35发表 [回复]
学习一下
11楼 wang679513 2010-10-13 00:12发表 [回复]
太高深
10楼 tphlj 2010-10-02 23:24发表 [回复]
我没写过插件系统,不过分析过一点
你可以去看看codeblocks的实现原理
Re: 好好学习_天天向上 2010-10-07 09:42发表 [回复]
codeblocks确实是一个很好的插件系统,应该是使用wxWidgets界面库的。
9楼 liushengbing 2010-09-30 19:38发表 [回复]
楼上不要这样极端嘛,可能实际都操作的差不多,只是因为描述不够大众化,插件与主程序只是用一套协议规定,就跟TCP一样的,
Re: 好好学习_天天向上 2010-10-02 15:37发表 [回复]
嗯,有道理。插件与主程序只是用一套协议规定。
8楼 cheungmine 2010-09-30 12:55发表 [回复]
简直是胡扯。2种解决方案,其一为跨平台方案:直接用XUL+XPCOM,类似FireFox。其二:微软DHTML+ActiveX+COM或XAML+WPF。
你文章中的设计根本实现出来就是不伦不类的,而且面临一堆的基础理论问题无法解决,最后的结果肯定是失败。
Re: 好好学习_天天向上 2010-09-30 18:54发表 [回复]
受教了,你的评论很有含金量。
Re: lvan100 2012-07-29 20:00发表 [回复]
回复clever101:如果只是为了实现一些简单的功能,我觉得这是一个不错的选择呀。
7楼 jamseyang 2010-09-30 10:58发表 [回复]
learnig...
6楼 cadinfo 2010-09-29 19:27发表 [回复]
[e10]这个应该已经触及系统架构设计,楼主谈到的所有要点我已经实现,但界面必定是不能用XML之类的配置文件的。
根据我的经验,我认为将业务设计分离为上策,即使做到底层库也应该分开而论,我这里做了如下一些:1.数据库代理层,2.UI代理层,3.业务层三个作为底层。插件服务器作为中间层,完成插件的所有事务管理(包括插件初始化和析构,UI的生成,用户权限管理,加密授权等)。客户应用程序是很薄的,短短几行代码即可。
这样做的好处是在设计上会取得回报,业务层的分离可以使这个插件架构能应付其他行业的快速开发。
有需要者可在csdn联系我,非诚勿扰!
Re: 好好学习_天天向上 2010-09-30 19:28发表 [回复]
多谢赐教!
5楼 lixiaohuprogram 2010-09-28 22:15发表 [回复]
学习!
4楼 yuyin86 2010-09-26 08:29发表 [回复]
学习了!!!!!
3楼 zzw_happy 2010-09-26 06:50发表 [回复]
有这么复杂吗?npapi是10几年前的浏览器插件接口,现在还在用。几10个函数接口而已。
Re: 好好学习_天天向上 2010-09-26 08:39发表 [回复]
学习了,知道了什么叫npapi。不过我看了下npapi的介绍,NPAPI是一个很经典的插件方案,用dll进行注入,用协定的API进行通信,用字符串描述插件能力。插件宿主(在这里就是浏览器...),会根据能力描述,动态加载插件,并负责插件调用的流程和生命周期管理。而插件中,负责真实逻辑的处理,并可以构造UI与用户交流。以此类方式实现的插件系统,往往是处理的逻辑比较固定适用范围一般(用API写死了逻辑...),但可扩展性不错(用字符串描述能力,可无限扩展...)。我感觉我的设计思路和这个差不多。
2楼 qiuwentianmingxin 2010-09-26 01:40发表 [回复]
[e01]原来用这个方法也可以
1楼 feifei870626 2010-09-25 21:33发表 [回复]
C++的回调用观察者模式就可以了。