Windows平台下C++插件系统实现的几个关键技术问题及其解决思路
根据我的实践,在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机制,大致的思路是在插件模块里使用钩子来截获所有窗口的鼠标键盘消息,这个思路我还没有更多的思考,但我想应该是可以的。
拉拉杂杂谈了一些插件系统实现的思路,希望能对大家能有所帮助。
from:
根据我的实践,在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机制,大致的思路是在插件模块里使用钩子来截获所有窗口的鼠标键盘消息,这个思路我还没有更多的思考,但我想应该是可以的。
拉拉杂杂谈了一些插件系统实现的思路,希望能对大家能有所帮助。
Windows平台下C++插件系统实现的几个关键技术问题及其解决思路的更多相关文章
- windows平台下 c++获取 系统版本 网卡 内存 CPU 硬盘 显卡信息<转>
GetsysInfo.h: #ifndef _H_GETSYSINFO #define _H_GETSYSINFO #pragma once #include <afxtempl.h> c ...
- 在Windows平台下Qt的exe报错问题排查步骤
在Windows平台下Qt的exe报错问题排查步骤 工具介绍: 1. Dependency Worker Dependency Worker是一个免费的用具用来扫描任何的32bit 或者64bit 的 ...
- [转]Windows平台下Makefile学习笔记
Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...
- Windows平台下Git服务器搭建
第一步:下载Java,下载地址:http://www.java.com/zh_CN/ 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键”计算机” => ”属性” = ...
- Windows平台下PHP开发环境的配置
Windows平台下PHP开发环境的配置 一.基本环境 1.Windows XP 32位 2.Apache 2.2.25,下载地址:http://mirror.bit.edu.cn/apache/ht ...
- Windows 平台下Git 服务器搭建
由于项目中一直在使用git作为版本管理,自己对git的理解.使用都还不是怎么的熟悉,所以准备深入了解一下git及一些常用命令的使用,于是干脆把服务端架上,通过自己的PC作为服务端同时作为客户端的角色进 ...
- windows平台下VLC2.0.5编译
windows平台下VLC2.0.5编译说明 时隔一年多,又要搞流媒体了,不过这次是要做流媒体服务器. 暂时决定使用vlc+ffmpeg+live555,虽然听有些前辈说这个组合的性能较差,只能作为学 ...
- 【转】Windows平台下Git服务器搭建
Windows平台下Git服务器搭建 Posted on 2015-05-18 21:29 阿祥当码农 阅读(7637) 评论(0) 编辑 收藏 该文章转自:http://www.codeceo.co ...
- Windows平台下的node.js安装
Windows平台下的node.js安装 直接去nodejs的官网http://nodejs.org/上下载nodejs安装程序,双击安装就可以了 测试安装是否成功: 在命令行输入 node –v 应 ...
随机推荐
- 将窗口置顶的方法:SetWindowPos、AttachThreadInput、SwitchToThisWindow
将窗口置顶的方法:SetWindowPos.AttachThreadInput.SwitchToThisWindow [转]http://hi.baidu.com/neil_danky/item/f9 ...
- C++学习之函数指针
C++学习之函数指针 和数据项类似,函数也有地址,函数的地址是存储在机器语言代码的内存的开始地址.通常,这些地址对用户而言,不重要也没什么用处,但对程序而言,它却很有用. 一.函数 ...
- VC++学习之网络编程中的套接字
VC++学习之网络编程中的套接字 套接字,简单的说就是通信双方的一种约定,用套接字中的相关函数来完成通信过程.应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问 ...
- hdu 2295 Radar 重复覆盖+二分
题目链接 给m个雷达, n个城市, 以及每个城市的坐标, m个雷达里只能使用k个, 在k个雷达包围所有城市的前提下, 求最小半径. 先求出每个雷达到所有城市的距离, 然后二分半径, 如果距离小于二分的 ...
- hdu 2471 简单DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2571 简单dp, dp[n][m] +=( dp[n-1][m],dp[n][m-1],d[i][k ...
- JAVA的BIT数组
写个小东西,要去重复数字,用到BIT数组,虽然JAVA已经提供了一个BitSet,不过自己手痒,又写了一个简单的 原理就不写了,网上一大堆 import java.util.Iterator; imp ...
- 7_Table Views
7 // // ViewController.swift // Table Views // // Created by ZC on 16/1/9. // Copyright © 2016年 ZC. ...
- 在CI框架下执行存储的方法
我直接把代码摆在这里分享哈 <?php /** * * Created by JetBrains PhpStorm. * User: lsl * Date: 14-1-8 * Time: 下午2 ...
- js正则验证"汉字"
var nickname = value; var regex = new RegExp("^([\u4E00-\uFA29]|[\uE7C7-\uE7F3]|[a-zA-Z0-9_]){1 ...
- 在 Windows Azure 上部署预配置 Oracle VM
Microsoft 和 Oracle 近期宣布建立战略合作伙伴关系,基于此,我们将通过 Windows Azure 镜像库推出多种常用的 Oracle 软件配置.即日起,客户可以在 Windows S ...