上面一篇文章大致描述了一下插件開(kāi)發(fā)框架整體結(jié)構(gòu)。這篇描述一下核心層的設(shè)計(jì)和實(shí)現(xiàn)。

          至于核心層的設(shè)計(jì),我想借鑒 一下微內(nèi)核的思想。核心層只負(fù)責(zé)實(shí)現(xiàn)下面幾個(gè)功能:

          1、 插件的加載,檢測(cè),初始化。

          2、 服務(wù)的注冊(cè)。

          3、 服務(wù)的調(diào)用。

          4、 服務(wù)的管理。

          插件的加載,檢測(cè),初始化

          插件的加載利用linux共享庫(kù)的動(dòng)態(tài)加載技術(shù)。具體的方法可以看一下IBM網(wǎng)站的一篇資料《Linux 動(dòng)態(tài)庫(kù)剖析》 。

          服務(wù)的注冊(cè)

          服務(wù)的注冊(cè)與調(diào)用采用表驅(qū)動(dòng)的方法。核心層中維護(hù)一個(gè)服務(wù)注冊(cè)表。

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

          驅(qū)動(dòng)表是一個(gè)數(shù)組,下標(biāo)為插件間交互消息類型,成員為插件提供的接收的消息處理函數(shù),由插件初始化的時(shí)候,調(diào)用插件框架的的注冊(cè)函數(shù)注冊(cè)到驅(qū)動(dòng)表。

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

                插件在函數(shù)PF_Init_Plugin中調(diào)用函數(shù)register_func來(lái)注冊(cè)插件要處理的消息類型。

          服務(wù)的調(diào)用
          //信元結(jié)構(gòu)體
          typedef struct Ele_St
          {
              Ele_Tag tag;
              Ele_Length len;
              Ele_Value  value;
              PEle_St next;
          }Ele_St, *PEle_St;
          //請(qǐng)求消息,信元流格式。
          typedef struct Req_Ele_Stream
          {
              Plugin_ID src_id;//源插件id
              Service_Type req_type;//請(qǐng)求類型
              PEle_St ele;
          } Req_Ele_Stream, *PReq_Ele_Stream;
          //響應(yīng)消息,信元流格式。
          typedef struct Rsp_Ele_Stream
          {
              Plugin_ID dest_id;//目的插件id
              Service_Type req_type;//響應(yīng)對(duì)應(yīng)的請(qǐng)求的類型。
              Execute_Result result;//記錄執(zhí)行結(jié)果
              Execute_Reason reason;//記錄執(zhí)行結(jié)果的原因
              PEle_St ele;
          } Rsp_Ele_Stream, *PRsp_Ele_Stream;
          //接收插件調(diào)用服務(wù)請(qǐng)求函數(shù),由插件提供,入?yún)檎?qǐng)求信元流。返回值為響應(yīng)信元流,用于同步請(qǐng)求處理。
          PRsp_Ele_Stream PF_Receive_Invoke_Proc(PReq_Ele_Stream pele_str);
          //插件收到響應(yīng)消息的處理入口函數(shù),由插件提供。如此為響應(yīng)信元流。
          void PF_Receive_Rsponse_Porc(PRsp_Ele_Stream pele_str);

          插件間的依賴關(guān)系是通過(guò)信元流來(lái)實(shí)現(xiàn)的。至于信元流的使用在我的另一篇博客《使用信元流(TLVStream)規(guī)范、簡(jiǎn)化模塊(C/C++)間交互 》 中有描述。插件對(duì)外的接口都是統(tǒng)一的。

          如果插件要和其他的插件通信,則調(diào)用PF_Init_Plugin函數(shù)的傳遞的服務(wù)調(diào)用接口: invoke_serv_func。插件框架根據(jù)信元流的類型,查找驅(qū)動(dòng)表,找到對(duì)應(yīng)的服務(wù)接收函數(shù)。插件用函數(shù) PF_Receive_Invoke_Proc接受其他插件的請(qǐng)求,此函數(shù)是插件想插件框架主動(dòng)注冊(cè)到驅(qū)動(dòng)表的。

          如果服務(wù)時(shí)同步的,這直接通過(guò)此函數(shù)返回,返回的信息在響應(yīng)信元流中。如果是異步的請(qǐng)求,這插件在處理完成后,通過(guò) send_rsp_func函數(shù)來(lái)發(fā)送響應(yīng)。

          插件的卸載
          //卸載插件時(shí)調(diào)用的函數(shù),類似于析構(gòu)函數(shù)。由插件提供,供插件框架卸載插件時(shí)調(diào)用。
          void PF_Destroy_Func();

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

          Copyright © 常高偉

          主站蜘蛛池模板: 横山县| 衡水市| 温宿县| 应用必备| 龙川县| 万荣县| 文成县| 江油市| 同心县| 宜州市| 威远县| 固镇县| 上高县| 盐池县| 卢氏县| 泊头市| 庆阳市| 井冈山市| 文安县| 广昌县| 息烽县| 兰西县| 昆山市| 博罗县| 吉林省| 都安| 五寨县| 汤原县| 海伦市| 南平市| 玉山县| 仪征市| 屏山县| 特克斯县| 廊坊市| 桦川县| 罗城| 临桂县| 靖安县| 澎湖县| 灵山县|