﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-常高伟的专栏-随笔分类-插件框架</title><link>http://www.blogjava.net/chgaowei/category/42125.html</link><description>思考、分享、交流、进步——为了自己的、公司的、中国的、世界的软件技术</description><language>zh-cn</language><lastBuildDate>Mon, 12 Oct 2009 12:32:51 GMT</lastBuildDate><pubDate>Mon, 12 Oct 2009 12:32:51 GMT</pubDate><ttl>60</ttl><item><title>构建自己的C/C++插件开发框架（四）&amp;mdash;&amp;mdash;核心层设计和实现</title><link>http://www.blogjava.net/chgaowei/archive/2009/10/12/297970.html</link><dc:creator>常高伟</dc:creator><author>常高伟</author><pubDate>Mon, 12 Oct 2009 12:20:00 GMT</pubDate><guid>http://www.blogjava.net/chgaowei/archive/2009/10/12/297970.html</guid><wfw:comment>http://www.blogjava.net/chgaowei/comments/297970.html</wfw:comment><comments>http://www.blogjava.net/chgaowei/archive/2009/10/12/297970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chgaowei/comments/commentRss/297970.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chgaowei/services/trackbacks/297970.html</trackback:ping><description><![CDATA[<p>上面一篇文章大致描述了一下插件开发框架整体结构。这篇描述一下核心层的设计和实现。 <p>至于核心层的设计，我想借鉴 一下微内核的思想。核心层只负责实现下面几个功能： <p>1、 插件的加载，检测，初始化。 <p>2、 服务的注册。 <p>3、 服务的调用。 <p>4、 服务的管理。 <p><strong>插件的加载，检测，初始化 </strong> <p>插件的加载利用linux共享库的动态加载技术。具体的方法可以看一下IBM网站的一篇资料<a href="http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/index.html">《Linux 动态库剖析》</a> 。 <p><strong>服务的注册</strong> <p>服务的注册与调用采用表驱动的方法。核心层中维护一个服务注册表。 <p>//插件间交互消息类型<br>typedef enum __Service_Type<br>{<br>&nbsp;&nbsp;&nbsp; Service_Max,<br>}Service_Type;<br>//插件用于和其他插件通信接口函数，由插件提供。<br>typedef PRsp_Ele_Stream (*PF_Invoke_Service_Func)(PReq_Ele_Stream pele_str);<br>//驱动表<br>typedef PF_Invoke_Service_Func Service_Drive_Table[Service_Max]; <p>驱动表是一个数组，下标为插件间交互消息类型，成员为插件提供的接收的消息处理函数，由插件初始化的时候，调用插件框架的的注册函数注册到驱动表。 <p>插件的初始化实现为：<br>//插件用于注册处理的消息类型的函数，由插件框架提供。<br>typedef RET_RESULT (*PF_Service_Register_Func)(Service_Type service_type);<br>//插件用于和其他插件通信接口函数，由插件框架提供。<br>typedef PRsp_Ele_Stream (*PF_Invoke_Service_Func)(PReq_Ele_Stream pele_str);<br>//插件回复响应函数。插件收到异步请求后，处理完成后，发送响应消息给请求的插件。由插件框架提供<br>typedef void (*PF_Send_Response_Func)(PRsp_Ele_Stream pele_str);<br>//初始化插件信息<br>typedef struct Plugin_Init_St<br>{<br>&nbsp;&nbsp;&nbsp; PF_Service_Register_Func register_func;//服务注册函数，要注册一系列的枚举值。插件可以处理的服务枚举值<br>&nbsp;&nbsp;&nbsp; PF_Invoke_Service_Func invoke_serv_func;//和其他组件交互时，调用的用于和其他组件交互的函数。发送请求消息。<br>&nbsp;&nbsp;&nbsp; PF_Send_Response_Func send_rsp_func;//再设计一个回复响应消息的接口。收到异步请求后，处理完毕后通知请求模块处理结果。<br>} Plugin_Init_St, *PPlugin_Init_St;<br>//初始化插件函数，类似于构造函数。由插件提供，供插件框架加载插件时初始化插件使用。<br>void PF_Init_Plugin(PPlugin_Init_St pinit_info); <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插件在函数PF_Init_Plugin中调用函数register_func来注册插件要处理的消息类型。 <p><strong>服务的调用</strong><br>//信元结构体<br>typedef struct Ele_St<br>{<br>&nbsp;&nbsp;&nbsp; Ele_Tag tag;<br>&nbsp;&nbsp;&nbsp; Ele_Length len;<br>&nbsp;&nbsp;&nbsp; Ele_Value&nbsp; value;<br>&nbsp;&nbsp;&nbsp; PEle_St next;<br>}Ele_St, *PEle_St;<br>//请求消息，信元流格式。<br>typedef struct Req_Ele_Stream<br>{<br>&nbsp;&nbsp;&nbsp; Plugin_ID src_id;//源插件id<br>&nbsp;&nbsp;&nbsp; Service_Type req_type;//请求类型<br>&nbsp;&nbsp;&nbsp; PEle_St ele;<br>} Req_Ele_Stream, *PReq_Ele_Stream;<br>//响应消息，信元流格式。<br>typedef struct Rsp_Ele_Stream<br>{<br>&nbsp;&nbsp;&nbsp; Plugin_ID dest_id;//目的插件id<br>&nbsp;&nbsp;&nbsp; Service_Type req_type;//响应对应的请求的类型。<br>&nbsp;&nbsp;&nbsp; Execute_Result result;//记录执行结果<br>&nbsp;&nbsp;&nbsp; Execute_Reason reason;//记录执行结果的原因<br>&nbsp;&nbsp;&nbsp; PEle_St ele;<br>} Rsp_Ele_Stream, *PRsp_Ele_Stream;<br>//接收插件调用服务请求函数，由插件提供，入参为请求信元流。返回值为响应信元流，用于同步请求处理。<br>PRsp_Ele_Stream PF_Receive_Invoke_Proc(PReq_Ele_Stream pele_str);<br>//插件收到响应消息的处理入口函数，由插件提供。如此为响应信元流。<br>void PF_Receive_Rsponse_Porc(PRsp_Ele_Stream pele_str); <p>插件间的依赖关系是通过信元流来实现的。至于信元流的使用在我的另一篇博客<a href="http://blog.csdn.net/chgaowei/archive/2009/09/05/4521983.aspx">《使用信元流（TLVStream）规范、简化模块（C/C++）间交互 》</a> 中有描述。插件对外的接口都是统一的。 <p>如果插件要和其他的插件通信，则调用PF_Init_Plugin函数的传递的服务调用接口： invoke_serv_func。插件框架根据信元流的类型，查找驱动表，找到对应的服务接收函数。插件用函数 PF_Receive_Invoke_Proc接受其他插件的请求，此函数是插件想插件框架主动注册到驱动表的。 <p>如果服务时同步的，这直接通过此函数返回，返回的信息在响应信元流中。如果是异步的请求，这插件在处理完成后，通过 send_rsp_func函数来发送响应。 <p><strong>插件的卸载</strong><br>//卸载插件时调用的函数，类似于析构函数。由插件提供，供插件框架卸载插件时调用。<br>void PF_Destroy_Func();</p><img src ="http://www.blogjava.net/chgaowei/aggbug/297970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chgaowei/" target="_blank">常高伟</a> 2009-10-12 20:20 <a href="http://www.blogjava.net/chgaowei/archive/2009/10/12/297970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>构建自己的C/C++插件开发框架（二）&amp;mdash;&amp;mdash;总体功能</title><link>http://www.blogjava.net/chgaowei/archive/2009/10/12/297968.html</link><dc:creator>常高伟</dc:creator><author>常高伟</author><pubDate>Mon, 12 Oct 2009 12:18:00 GMT</pubDate><guid>http://www.blogjava.net/chgaowei/archive/2009/10/12/297968.html</guid><wfw:comment>http://www.blogjava.net/chgaowei/comments/297968.html</wfw:comment><comments>http://www.blogjava.net/chgaowei/archive/2009/10/12/297968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chgaowei/comments/commentRss/297968.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chgaowei/services/trackbacks/297968.html</trackback:ping><description><![CDATA[<p>在这一系列的上一个文章中，介绍了构建C/C++插件开发框架的初步设想，下面我会一步步的向下展开，来实现我的这个设想。 <p>今天主要谈一下我对这个框架的功能认识，或是期望。昨天看了一篇关于<a href="http://blog.csdn.net/tony1130/archive/2009/09/03/4516948.aspx">持续集成能力成熟度模型</a> 的一篇文章，受此启发，我对此框架的认识渐渐清晰。 <p>这个框架可以当做我们公司底层产品（交换机，资源服务器等）的基础设施。上层基于java开发的产品可以直接在OSGI上开发。 <p><strong>核心功能：</strong> <p>1、最重要的一个功能是，提供一个模块化的编程模型，促进模块化软件开发，真正的实现针对接口编程。 <p>2、提供一个有助于提高模块可重用性的基础设施。 <p>3、提供一个C/C++插件的运行环境。 <p>4、提供一个动态插件框架，插件可以动态更改，而无需重启系统。这个功能虽然不难实现，但是用处好像不是很大。 <hr>  <p><strong>扩展部分功能：</strong> <p>1、支持分布式系统结构，多个运行框架组合起来形成一个系统，对模块内部隐藏远程通讯细节。 <p>2、支持系统的分层架构。 <p>3、能够和其他的开发框架进行集成，比如OSGI，SCA等。 <p>4、多个运行框架中，能够实现对运行框架的有效管理。 <p>5、概念上要实现类似于SCA中component（构件），composite（组合构件），Domain（域）的概念。 <hr>  <p><strong>开发部分功能：</strong> <p>1、为了简化开发，开发一个Eclipse插件，用于开发框架中的C/C++插件。能够根据插件开发向导，最终生成符合插件规范的公共代码，配置文件，Makefile文件等。 <hr>  <p><strong>调试部分功能：</strong> <p>1、提供一个统一的日志处理函数，可以集成Log4cpp。 <p>2、提供模块间的消息日志，以及框架对外的接口日志。 <p>3、提供消息和日志的追踪功能，能将和某事件相关的消息和日志单独提取出来。 <p>4、提供资源监测功能，监测对资源（内存，套接字，文件句柄等）的使用情况。 <hr>  <p><strong>测试部分功能：</strong> <p>1、集成一些单元测试框架，比如unitcpp，达到自动化单元测试的目标。 <p>2、自己实现自动化集成测试框架，并且开发相应的Eclipse插件，简化集成测试（利用脚本和信元流）。 <p>3、集成原有的自动化功能测试框架flowtest，并且开发相应的Eclipse插件，简化功能测试。 <p>4、实现性能测试，监测框架。 <hr>  <p><strong>部署部分功能：</strong> <p>1、实现自动化部署。特别是在分布式应用的情况下。 <p>2、提供一个命令行程序，通过命令更改系统配置，管理插件。</p><img src ="http://www.blogjava.net/chgaowei/aggbug/297968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chgaowei/" target="_blank">常高伟</a> 2009-10-12 20:18 <a href="http://www.blogjava.net/chgaowei/archive/2009/10/12/297968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>构建自己的C/C++插件开发框架（一）&amp;mdash;&amp;mdash;初步设想</title><link>http://www.blogjava.net/chgaowei/archive/2009/10/12/297966.html</link><dc:creator>常高伟</dc:creator><author>常高伟</author><pubDate>Mon, 12 Oct 2009 12:16:00 GMT</pubDate><guid>http://www.blogjava.net/chgaowei/archive/2009/10/12/297966.html</guid><wfw:comment>http://www.blogjava.net/chgaowei/comments/297966.html</wfw:comment><comments>http://www.blogjava.net/chgaowei/archive/2009/10/12/297966.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chgaowei/comments/commentRss/297966.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chgaowei/services/trackbacks/297966.html</trackback:ping><description><![CDATA[<p>　最近一直在学习OSGI方面的知识。买了一本《OSGI原理和最佳实践》，可是还没有到。遗憾的是，OSGI目前的几个开源框架只支持Java，对C和C++都不支持的。可惜我们公司目前主要的开发语言还是c和c++，即便是引进OSGI，所得的好处范围有限。而我对松散耦合的模块化开发向往已久。查了一下OSGI对C++支持的好像是有一个开源项目，不过好像应用范围很小。而SCA标准中是有对C++实现模型的支持的，但是几个开源的框架目前还只支持JAVA。 <p>　　昨天看了丁亮的转载的一篇博客《<strong>C/C++：构建你自己的插件框架 </strong>》，原文的链接：<a href="http://blog.chinaunix.net/u/12783/showart_662937.html">http://blog.chinaunix.net/u/12783/showart_662937.html</a> 。看了一下里面讲的方法，自己倒是可以实现。所以有了构建自己的c/c++插件开发框架的想法。今天先写一下初步的设想。 <p><strong>C/C++插件开发框架的要素</strong> <p>　　BlueDavy有一篇介绍服务框架要素的文章（链接：<a href="http://www.blogjava.net/BlueDavy/archive/2009/08/28/172259.html">http://www.blogjava.net/BlueDavy/archive/2009/08/28/172259.html</a> ）。我的插件框架也要考虑、解决以下的几个问题： <p>　　1、如何注册插件； <p>　　2、如何调用插件； <p>　　3、如何测试插件； <p>　　4、插件的生命周期管理； <p>　　5、插件的管理和维护； <p>　　6、插件的组装； <p>　　7、插件的出错处理； <p>　　8、服务事件的广播和订阅（这个目前还没有考虑要支持）； <p>　　其中有几个点很重要：1）插件框架要能够使模块松散耦合，做到真正的面向接口编程；2）框架要支持自动化测试：包括单元测试，集成测试；3）简化部署；4）支持分布式，模块可以调用框架外的插件。 <p><strong>采用的技术</strong><br>　　插件框架要解决的一个问题就是插件的动态加载能力。这里可以使用共享库的动态加载技术。当然，为了简单，第一步只考虑做一个linux下的插件框架。 <p><strong>　　总体结构</strong> <p>　　框架的总体结构上，参考OSGI的“微内核+系统插件+应用插件”结构。这里要好好考虑一下把什么做在内核中。关于微内核结构，以前我做个一个微内核流程引擎，会在后面有时间和大家分享。 <p>　　框架中模块间的数据传送，有两种解决方法：一是普元采用的XML数据总线的做法。优点是扩展性好，可读性好。但是速度有些慢。二是采用我熟悉的信元流。优点的效率高，访问方便，但是可读性差一点，另外跨框架的数据传送，需要考虑网络字节序的问题。 <p>　　对于框架间的通信，通过系统插件封装，对应用插件隐藏通信细节。 <p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 部署</strong> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 努力做到一键式部署。</p><img src ="http://www.blogjava.net/chgaowei/aggbug/297966.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chgaowei/" target="_blank">常高伟</a> 2009-10-12 20:16 <a href="http://www.blogjava.net/chgaowei/archive/2009/10/12/297966.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>