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机制,大致的思路是在插件模块里使用钩子来截获所有窗口的鼠标键盘消息,这个思路我还没有更多的思考,但我想应该是可以的。

      拉拉杂杂谈了一些插件系统实现的思路,希望能对大家能有所帮助。

 

 

时间: 2022-10-19

Windows平台下C++插件系统实现的几个关键技术问题及其解决思路的相关文章

ssl-关于windows平台下的server端AcquireCredentialsHandle调用失败问题

问题描述 关于windows平台下的server端AcquireCredentialsHandle调用失败问题 securityFuns.AcquireCredentialsHandle执行后,返回1312错误码.如下代码: #include <schannel.h>#define SECURITY_WIN32#include <security.h>#pragma comment(libcrypt32.lib"")int _tmain(int argc _TC

&lt;转&gt;Windows平台下Makefile学习笔记(二)

  本文转自:http://blog.csdn.net/clever101/article/details/8286066         上次我们学习了怎么用Makefile编译一个控制台工程.这次我们学习一下如何使用Makefile来编译一个win 32的GUI程序.win 32的GUI程序其编译过程大部分和控制台程序一样,不同的是多了一步RC编译器将资源文件编译成res文件,然后在最后一步链接中需要把这个res文件链接到exe文件中.         好,现在让我们在实践中学习吧.新建一个

win764位平台下,注册的shell扩展dll不起作用,如何解决?

问题描述 win764位平台下,注册的shell扩展dll不起作用,如何解决? win764位平台下,注册的shell扩展编译成64位dll经注册后可以成功注入到explorer进程,但是没有实际效果,如何解决? 解决方案 首先,你实现的所有的接口,是不是64bit的sdk提供的那些.另外,你确认你正确安装了你的扩展没有.你怎么确认它注入成功的. 解决方案二: https://code.msdn.microsoft.com/windowsapps/CppShellExtContextMenuHa

《中国人工智能学会通讯》——1.16 聊天机器人系统的组成结构及关键 技术

1.16 聊天机器人系统的组成结构及关键 技术 通常来说,聊天机器人的系统框架如图 1 所示,包含五个主要的功能模块.语音识别模块负责接收用户的语音输入,并将其转换成文字形式交由自然语言理解模块进行处理.自然语言理解模块在理解了用户输入的语义之后,将特定的语义表达式输入到对话管理模块中.对话管理模块负责协调各个模块的调用及维护当前对话状态,选择特定的回复方式并交由自然语言生成模块进行处理.自然语言生成模块生成回复文本输入给语音合成模块,将文字转换成语音输出给用户.这里我们仅以文本输入形式为例介绍

windows平台下,c++获取cpu型号,读取注册表获取系统软硬件信息代码

   下面的代码可以用于跨平台设备信息的获取 搭建传输的socket平台参考下面博文:   http://blog.csdn.net/wangyaninglm/article/details/41940287       GetsysInfo.h:   #ifndef _H_GETSYSINFO #define _H_GETSYSINFO #pragma once #include <afxtempl.h> class GetSysInfo { public: GetSysInfo(void)

Windows平台下Git服务器搭建

  第一步:下载Java 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键"计算机" => "属性" => "高级系统设置" => "高级" => "环境变量" => "系统变量". 新建: 变量名:JAVA_HOME 变量值:D:/Program Files (x86)/Java/jdk1.6.0_21[具体要根据你自己的安装

Windows平台下MySQL常用操作与命令_Mysql

1.导出整个数据库 mysqldump -u 用户名 -p --default-character-set=latin1 数据库名 > 导出的文件名(数据库默认编码是latin1) mysqldump -u wcnc -p smgp_apps_wcnc > wcnc.sql 2.导出一个表 mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名 mysqldump -u wcnc -p smgp_apps_wcnc users> wcnc_users.sql 3.导

Windows平台下tomcat+java的web程序持续占cpu问题调试

1.问题 Tomcat服务器跑了一段时间后,发现Tomcat进程占用的CPU资源在80%-100%间,加上其它的进程,整个服务器的CPU处理100%运行状态. 2.通过process explorer查看Tomcat进程下的线程 process explorer下载:https://technet.microsoft.com/en-us/sysinternals/bb896653/ 我使用的是汉化后的版本:http://download.csdn.net/detail/p_3er/9169985

关于WINDOWS平台下RMAN备份移植

(自己写的) SID一样1 移动RMAN备份文件 包括归档日志 控制文件 数据文件 INITFILE SPFILE.2 shutdown测试数据库.删除所有ORADATA下面的数据文件,控制文件,日志文件.3 使用生产数据库中的PFILE或者SPFILE启动数据库 到NOMOUNT状态下.4 restore  controlfile from '备份控制文件位置';(注意恢复备份文件的位置要和原数据库一样).5 重新建立PWDSID.ORA   orapwd file= password= en