上面一篇文章大致描述了一下插件開發框架整體結構。這篇描述一下核心層的設計和實現。

          至于核心層的設計,我想借鑒 一下微內核的思想。核心層只負責實現下面幾個功能:

          1、 插件的加載,檢測,初始化。

          2、 服務的注冊。

          3、 服務的調用。

          4、 服務的管理。

          插件的加載,檢測,初始化

          插件的加載利用linux共享庫的動態加載技術。具體的方法可以看一下IBM網站的一篇資料《Linux 動態庫剖析》

          服務的注冊

          服務的注冊與調用采用表驅動的方法。核心層中維護一個服務注冊表。

          //插件間交互消息類型
          typedef enum __Service_Type
          {
              Service_Max,
          }Service_Type;
          //插件用于和其他插件通信接口函數,由插件提供。
          typedef PRsp_Ele_Stream (*PF_Invoke_Service_Func)(PReq_Ele_Stream pele_str);
          //驅動表
          typedef PF_Invoke_Service_Func Service_Drive_Table[Service_Max];

          驅動表是一個數組,下標為插件間交互消息類型,成員為插件提供的接收的消息處理函數,由插件初始化的時候,調用插件框架的的注冊函數注冊到驅動表。

          插件的初始化實現為:
          //插件用于注冊處理的消息類型的函數,由插件框架提供。
          typedef RET_RESULT (*PF_Service_Register_Func)(Service_Type service_type);
          //插件用于和其他插件通信接口函數,由插件框架提供。
          typedef PRsp_Ele_Stream (*PF_Invoke_Service_Func)(PReq_Ele_Stream pele_str);
          //插件回復響應函數。插件收到異步請求后,處理完成后,發送響應消息給請求的插件。由插件框架提供
          typedef void (*PF_Send_Response_Func)(PRsp_Ele_Stream pele_str);
          //初始化插件信息
          typedef struct Plugin_Init_St
          {
              PF_Service_Register_Func register_func;//服務注冊函數,要注冊一系列的枚舉值。插件可以處理的服務枚舉值
              PF_Invoke_Service_Func invoke_serv_func;//和其他組件交互時,調用的用于和其他組件交互的函數。發送請求消息。
              PF_Send_Response_Func send_rsp_func;//再設計一個回復響應消息的接口。收到異步請求后,處理完畢后通知請求模塊處理結果。
          } Plugin_Init_St, *PPlugin_Init_St;
          //初始化插件函數,類似于構造函數。由插件提供,供插件框架加載插件時初始化插件使用。
          void PF_Init_Plugin(PPlugin_Init_St pinit_info);

                插件在函數PF_Init_Plugin中調用函數register_func來注冊插件要處理的消息類型。

          服務的調用
          //信元結構體
          typedef struct Ele_St
          {
              Ele_Tag tag;
              Ele_Length len;
              Ele_Value  value;
              PEle_St next;
          }Ele_St, *PEle_St;
          //請求消息,信元流格式。
          typedef struct Req_Ele_Stream
          {
              Plugin_ID src_id;//源插件id
              Service_Type req_type;//請求類型
              PEle_St ele;
          } Req_Ele_Stream, *PReq_Ele_Stream;
          //響應消息,信元流格式。
          typedef struct Rsp_Ele_Stream
          {
              Plugin_ID dest_id;//目的插件id
              Service_Type req_type;//響應對應的請求的類型。
              Execute_Result result;//記錄執行結果
              Execute_Reason reason;//記錄執行結果的原因
              PEle_St ele;
          } Rsp_Ele_Stream, *PRsp_Ele_Stream;
          //接收插件調用服務請求函數,由插件提供,入參為請求信元流。返回值為響應信元流,用于同步請求處理。
          PRsp_Ele_Stream PF_Receive_Invoke_Proc(PReq_Ele_Stream pele_str);
          //插件收到響應消息的處理入口函數,由插件提供。如此為響應信元流。
          void PF_Receive_Rsponse_Porc(PRsp_Ele_Stream pele_str);

          插件間的依賴關系是通過信元流來實現的。至于信元流的使用在我的另一篇博客《使用信元流(TLVStream)規范、簡化模塊(C/C++)間交互 》 中有描述。插件對外的接口都是統一的。

          如果插件要和其他的插件通信,則調用PF_Init_Plugin函數的傳遞的服務調用接口: invoke_serv_func。插件框架根據信元流的類型,查找驅動表,找到對應的服務接收函數。插件用函數 PF_Receive_Invoke_Proc接受其他插件的請求,此函數是插件想插件框架主動注冊到驅動表的。

          如果服務時同步的,這直接通過此函數返回,返回的信息在響應信元流中。如果是異步的請求,這插件在處理完成后,通過 send_rsp_func函數來發送響應。

          插件的卸載
          //卸載插件時調用的函數,類似于析構函數。由插件提供,供插件框架卸載插件時調用。
          void PF_Destroy_Func();

          posts - 19, comments - 0, trackbacks - 0, articles - 0

          Copyright © 常高偉

          主站蜘蛛池模板: 双城市| 利津县| 北流市| 巴青县| 临洮县| 万盛区| 左权县| 东源县| 图木舒克市| 怀安县| 沁源县| 东海县| 长兴县| 晋城| 乾安县| 广灵县| 金塔县| 屏东市| 环江| 丰台区| 自治县| 鄱阳县| 永和县| 化州市| 巴彦淖尔市| 二连浩特市| 海淀区| 婺源县| 永德县| 蕲春县| 五家渠市| 纳雍县| 临朐县| 江华| 鞍山市| 磐安县| 余姚市| 新乡市| 临沂市| 满城县| 岳西县|