一種基于插件機制的動態加載組件方法和系統的制作方法【專利摘要】本發明涉及一種基于插件機制的動態加載組件方法和系統,所述方法包括:應用程序或組件在接收到需要調用其它組件中的相應功能指令時,查找所述其它組件,所述其它組件提供標準插件接口,具有唯一標識其身份的“MIMEType”;查找到所述組件后,將所述組件加載到內存中,并獲取創建所述組件實例的接口以及調用所述組件的相應功能接口;在不需要所述的相應功能時,調用卸載組件接口,將所述其他組件卸載。本發明實施例所述接口為標準插件接口,在編譯時不鏈接組件,在應用程序啟動時不加載不必要的組件,節省了內存,避免了針對不同業務形態的嵌入式系統生成不同版本的應用程序。【專利說明】一種基于插件機制的動態加載組件方法和系統【
技術領域:
】[0001]本發明涉及計算機應用程序發現和組件加載【
技術領域:
】,尤其涉及一種基于插件機制的動態加載組件方法和系統。【
背景技術:
】[0002]目前,組件技術被廣泛應用于嵌入式系統中。在嵌入式系統中,系統的業務形態較多,不同形態下中間件或應用程序的功能不同,需加載的組件也不同,現有技術通常是在編譯時必須鏈接組件,這樣對于相同的中間件或應用程序,需要為每個業務形態的系統鏈接不同的組件,生成不同版本,使用這種方法使得中間件或應用程序后續的軟件維護工作量大。此外,嵌入式系統包括內存在內的硬件資源非常有限,編譯鏈接組件庫后,在應用程序啟動時就加載所有組件,不必要地耗費了內存。[0003]現有動態加載組件流程都是私有的,都是通過定義一些私有函數接口實現對組件庫的查找和對組件庫方法的調用,這種方法限制了其通用型,封裝的接口只對某個具體的組件庫有效,對別的組件庫就沒有作用了。【
發明內容】[0004]本發明的目的在于,為克服上述問題,本發明提出一種基于插件機制的動態加載組件方法和系統。[0005]為實現上述目的,本發明提供了一種嵌入式系統的動態加載組件的方法,所述方法包含:[0006]步驟101)封裝組件庫;[0007]步驟102)當某個應用程序或組件收到需要調用另一個組件中的相應功能指令時,依據標識該另一組件身份的“MMEType”,遍歷系統中的各組件庫的“MMEType”來查找所述其它組件;[0008]步驟103)當查找到所需組件后,在內存中加載所需組件,并獲取創建所需組件實例的接口以及調用所需組件的相應功能接口;[0009]其中,所有組件均具有唯——個標識其身份的“MMEType”。[0010]上述步驟103)之后還包含:[0011]調用卸載組件接口,卸載加載的組件。[0012]采用插件標準NPAPI接口函數封裝組件庫。[0013]采用插件標準NPAPI接口函數封裝組件庫的方法具體包含如下步驟:[0014]在編譯組件庫的時候加入npruntime.h、np_entry.cpp、npn_gate.cpp、npp_gate.cpp以及設置插件調用接口的def文件;所述npruntime.h為頭文件,np_entry.cpp、npn_gate,cpp、npp_gate.cpp為接口函數,且接口函數np_entry.cpp、npn_gate.cpp和npp_gate,cpp定義在npruntime.h頭文件中;[0015]其中,[0016]np_entry.cpp中定義了三個接口,分別是:[0017]NP_GetEntryPoints-在插件加載之后立即調用該接口,用于瀏覽器獲取所有可能需要調用的API函數的指針;[0018]NP_Initialize-為插件提供全局初始化;[0019]NP_Shutdown-為插件提供全局反初始化;[0020]npn_gate.cpp文件用于實現20個函數接口,且這些接口是由瀏覽器實現的;在插件實例初始化的時候,將瀏覽器實現的這些函數的入口地址保存到一個NPNetscapeFuncs結構中,這些函數的實現就直接根據NPNetscapeFuncs結構中的入口地址調用瀏覽器實現的相關功能;且在開發插件時只需要調用NPN_開頭的全局函數即可;[0021]npp_gate.cpp文件用于實現包含如下幾個函數接口:[0022]NPP_ShutdownO:在卸載一個插件DLL之前及刪除任何插件實例之后調用;[0023]NPP_New():在創建一個插件實例時調用,用來初始化插件的實例數據結構;[0024]NPP_Destroy():在刪除一個插件實例時調用,用于釋放為插件實例所分配的空間;[0025]NPP_GetMIMEDescript1n():僅用于Unix環境,用于獲取由該插件所支持的MIME類型;[0026]其中,Def文件用來設置插件供外部調用的接口,接口一般有三個,分別是NP_GetEntryPoints、NP_Initialize和NP_Shutdown;[0027]當組件庫完成封裝之后,如果某個應用程序或組件需要調用采用插件標準NPAPI接口函數封裝的組件庫的時候,通過調用NP_GetEntryPoints、NP_Initialize和NP_Shutdown這三個接口實現對組件庫方法的調用。瀏覽器在組件加載后調用NP_GetEntryPoints接口,獲取所有可能需要調用的API函數的指針,獲取的函數指針中就包含有NP_Initialize接口函數指針;然后調用NP_Initialize接口對組件進行全局初始化,初始化后獲得一系列NPN類和NPP類函數接口的指針,獲得的NPP類函數接口的指針中就包含有NPP_GetMIMEDescript1n接口函數指針;通過調用NPP_GetMIMEDescript1n接口函數,就能獲得該組件支持的“MMEType”。[0028]遍歷系統中各組件庫的特征接口進而查找所需組件;[0029]組件封裝之后,把封裝好的組件文件放在指定目錄下,當解析頁面遇到需要調用組件的方法時,加載所需組件;加載所需組件前,應用程序或組件首先遍歷系統中的各組件庫的“MMEType”來查找所述組件,找到與指定所需組件的“MMEType”值相同的組件,進而加載所需組件。[0030]上述步驟103)進一步包含:[0031]加載組件時會調用NP_InitializeO進行初始化,初始化后獲得一系列NPN類和NPP類函數接口的指針,然后調用NPP_New()函數接口創建組件實例并初始化,實例對象的構造函數中會生成ScriptablePluginObject對象,倉Il建組件實例后,當遇到需要調用組件中的方法,根據組件方法的名稱,去調用ScriptablePluginObject:HasMethod來判斷是否有這個方法,如果有這個方法,則會觸發ScriptablePluginObject::1nvoke函數運行,invoke函數內部根據方法名稱實現對應的操作。[0032]此外,本發明還提供了一種嵌入式系統的動態加載組件的系統,所述系統包含:[0033]封裝模塊,用于把組件用插件標準NPAPI接口封裝,實現像調用標準插件那樣通過標準接口去查找組件并調用組件的方法;[0034]查找模塊,用于遍歷存放有多個組件庫的目錄,尋找到所需要調用的組件庫;和調用模塊,用于查找所需組件庫后去調用具體的方法實現相應的功能。[0035]與現有技術相比,本發明的技術優勢在于:本【
發明內容】是基于標準插件流程的,封裝組件庫所用的接口函數不是自己定義的私有接口函數,而是插件標準NPAPI接口函數。本專利【
發明內容】的的封裝規則同時適用于多個組件庫,組件庫只要按本專利的方法封裝,第三方庫或者應用程序就可以通過標準接口實現對組件庫的查找以及對組件庫方法的調用,不用具體區分是哪個組件庫,大大提高了動態加載組件的通用性。【專利附圖】【附圖說明】[0036]圖1是本發明實施例的嵌入式瀏覽器動態查找和加載組件流程示意圖;[0037]圖2是本發明實施例嵌入式系統組件加載方法示意圖。【具體實施方式】[0038]下面通過附圖和實施例,對本發明實施例的技術方案做進一步的詳細描述。[0039]本發明提供了一種基于插件機制的動態加載組件方法,所述方法包括:[0040]應用程序或組件在接收到需要調用標準插件NPAPI封裝的其它組件中的相應功能指令時,查找所述其它組件,所述其它組件具有唯一標識其身份的“MMEType”;[0041]查找到所述組件后,將所述組件加載到內存中,并獲取創建所述組件實例的接口以及調用所述組件的相應功能接口;[0042]在不需要所述的相應功能時,調用卸載組件接口,將所述其他組件卸載。[0043]上述其它組件使用標準插件接口NPAPI封裝;[0044]上述查找其他組件的方法符合標準插件加載過程,具體為:遍歷系統中各組件庫的特征接口來查找所述其它組件;加載所述其它組件前,應用程序或組件首先會取得平臺上存在的所有所述其它組件類型,保存所述其它組件的路徑和名稱,然后在解析網頁遇到指定插件時,會去遍歷系統中的各組件庫的“MMEType”值,找到與指定所述其它組件的"MIMEType”值相同的組件庫,進而加載正確的所述其它組件。[0045]優選地,應用程序或組件啟動時不加載所述其它組件。[0046]優選地,應用程序在編譯階段時不鏈接所述其它組件。[0047]優選地,所述其它組件具有唯一標識其身份的“MMEType”,具體為:不同的所述其它組件擁有不同的“MMEType”類型,這是表示所述其它組件本身唯一的標識。應用程序或組件就是通過此類型標識來識別特定的插件,進而調用所述其它組件的API函數。[0048]采用插件標準NPAPI接口函數封裝組件庫的方法具體包含如下步驟:[0049]在編譯組件庫的時候加入npruntime.h、np_entry.cpp、npn_gate.cpp、npp_gate.cpp以及設置插件調用接口的def文件;所述npruntime.h為頭文件,np_entry.cpp、npn_gate,cpp、npp_gate.cpp為接口函數,且接口函數np_entry.cpp、npn_gate.cpp和npp_gate,cpp定義在npruntime.h頭文件中;[0050]其中,[0051]np_entry.cpp中定義了三個接口,分別是:[0052]NP_GetEntryPoints-在插件加載之后立即調用該接口,用于瀏覽器獲取所有可能需要調用的API函數的指針;[0053]NP_Initialize-為插件提供全局初始化;[0054]NP_Shutdown-為插件提供全局反初始化;[0055]npn_gate.cpp文件用于實現20個函數接口,且這些接口是由瀏覽器實現的;在插件實例初始化的時候,將瀏覽器實現的這些函數的入口地址保存到一個NPNetscapeFuncs結構中,這些函數的實現就直接根據NPNetscapeFuncs結構中的入口地址調用瀏覽器實現的相關功能;且在開發插件時只需要調用NPN_開頭的全局函數即可;[0056]npp_gate.cpp文件用于實現包含如下幾個函數接口:[0057]NPP_Shutdown():在卸載一個插件動態鏈接庫之前及刪除任何插件實例之后調用;[0058]NPP_New():在創建一個插件實例時調用,用來初始化插件的實例數據結構;[0059]NPP_DestroyO:在刪除一個插件實例時調用,用于釋放為插件實例所分配的空間;[0060]NPP_GetMIMEDescript1n():僅用于Unix環境,用于獲取由該插件所支持的MIME類型;[0061]其中,Def文件用來設置插件供外部調用的接口,接口一般有三個,分別是NP_GetEntryPoints、NP_Initialize和NP_Shutdown;[0062]當組件庫完成封裝之后,如果某個應用程序或組件需要調用采用插件標準NPAPI接口函數封裝的組件庫的時候,通過調用NP_GetEntryPoints、NP_Initialize和NP_Shutdown這三個接口實現對組件庫方法的調用。瀏覽器在組件加載后調用NP_GetEntryPoints接口,獲取所有可能需要調用的API函數的指針,獲取的函數指針中就包含有NP_Initialize接口函數指針;然后調用NP_Initialize接口對組件進行全局初始化,初始化后獲得一系列NPN類和NPP類函數接口的指針,獲得的NPP類函數接口的指針中就包含有NPP_GetMIMEDescript1n接口函數指針;通過調用NPP_GetMIMEDescript1n接口函數,就能獲得該組件支持的“MMEType”。[0063]本發明實施例所述接口為標準插件的NPAPI接口,在編譯時不鏈接組件,在應用程序啟動時不加載不必要的組件,節省了內存,避免了針對不同業務形態的嵌入式系統生成不同版本的應用程序。[0064]實施例1:[0065]本發明實施例包含以下步驟:[0066]步驟1,為各組件配置具有可唯一標識其身份的“MMEType”。[0067]步驟2,應用程序或其他組件在接收到需要調用其它組件相應功能指令時,通過遍歷系統中指定目錄下各組件庫的特征接口來查找組件;所述的遍歷手段在順序上沒有先后限制。[0068]步驟3,如果存在該組件,則將組件加載到內存中,并獲取組件實例、調用封裝組件的插件標準NPAPI接口;[0069]步驟4,在退出相應功能模塊時,卸載組件,釋放內存。[0070]其中,唯一標識組件身份的“MMEType”可使用以下方法:[0071]把唯一標識組件身份的“MIMEType”設置為applicat1n/χ-組件名稱。[0072]本發明實施例根據嵌入式系統的特點,只在具備組件功能的系統中以及在啟動組件功能時加載組件,避免了應用程序為不同業務形態的系統生成不同版本,減少了應用程序啟動時加載組件耗費的內存。[0073]實施例2[0074]下面通過一個優選實施例對本發明實施例的方法做進一步闡述:[0075]圖1是本發明實施例的嵌入式瀏覽器動態查找和加載組件流程示意圖。以嵌入式瀏覽器作為具體的應用程序。當前網頁以其跨平臺、易部署等特點成為嵌入式系統中的主流門戶導航,嵌入式瀏覽器是解析網頁的核心,在不同業務系統中需求不同,需要加載不同組件的功能,比如對于雙模機頂盒需要使用DVB組件庫,但互聯網機頂盒不需要DVB組件庫。通過本發明實施例方法,所述嵌入式瀏覽器可以動態發現和加載本地功能組件,無須為不同業務系統編譯不同版本,并且只在啟動相應功能時才加載組件。[0076]本實例中組件創建實例的特征接口是調用的插件標準NPAPI中的NPP_NewO接口函數,撤銷實例的特征接口是調用的插件標準NPAPI中的NPP_NewO接口函數。此外組件的功能接口都是C++類,因此瀏覽器與組件庫之間需要定義一個與組件接口一一對應的基類,以供加載組件后能得到組件C++實例對象并使用其方法。[0077]此外,本實例的系統可以基于Linux操作系統,組件編譯成動態庫(.so),瀏覽器使用Linux系統函數dlopen、dlclose、dlsym來打開、關閉組件庫以及執行組件的接口,具體可以包括以下步驟:[0078]瀏覽器定義一個基類,該基類中的方法與組件接口一一對應;[0079]組件繼承瀏覽器提供的基類,實現其派生類,然后用插件標準NPAPI接口函數封裝組件庫,編譯成動態庫;[0080]在具備該組件功能的系統中,將組件庫的路徑加入配置文件;[0081]當頁面解析到需要調用組件的功能接口后,瀏覽器讀取配置文件中的庫目錄路徑,在該路徑下遍歷庫,通過組件特征接口“MMEType”去查找相應的組件庫,如果沒有該接口則返回錯誤;[0082]如果有與組件名稱對應的組件庫,則調用Dlopen打開該組件對象對應的組件庫,然后通過dlsym函數找到庫中的NP-1nitializeO函數用來調用,調用np-1nitializeO函數后獲得NPP-newO地址,然后調用NPP-new()創建實例。[0083]然后通過方法名稱直接調用組件對象實例的方法,以實現相應功能;[0084]當離開頁面時,調用插件標準NPAPI接口函數NPP_Destroy銷毀組件對象實例,然后調用插件標準NPAPI接口函數NPP_Shutdown關閉組件庫。[0085]為更加清楚地展示本發明實施例的方法,圖2展示了本發明實施例嵌入式系統組件加載方法示意圖。從圖2可見:所述方法包括:應用程序或組件在接收到需要調用標準插件NPAPI封裝的其它組件中的相應功能指令時,查找所述其它組件,所述其它組件具有唯一標識其身份的“MIMEType”;查找到所述組件后,將所述組件加載到內存中,并獲取創建所述組件實例的接口以及調用所述組件的相應功能接口;在不需要所述的相應功能時,調用卸載組件接口,將所述其他組件卸載。[0086]優選地,所述查找其他組件,具體為:遍歷系統中各組件庫的特征接口來查找所述其它組件;加載所述其它組件前,應用程序或組件首先會取得平臺上存在的所有所述其它組件類型,保存所述其它組件的路徑和名稱,然后在解析網頁遇到指定插件時,會去遍歷系統中的各組件庫的“MMEType”值,找到與指定所述其它組件的“MMEType”值相同的組件庫,進而加載正確的所述其它組件。[0087]優選地,應用程序或組件啟動時不加載所述其它組件。[0088]優選地,應用程序在編譯階段時不鏈接所述其它組件。[0089]優選地,所述其它組件具有唯一標識其身份的“MMEType”,具體為:不同的所述其它組件擁有不同的“MMEType”類型,這是表示所述其它組件本身唯一的標識。應用程序或組件就是通過此類型標識來識別特定的插件,進而調用所述其它組件的API函數。[0090]本發明實施例所述接口為標準插件的NPAPI接口,在編譯時不鏈接組件,在應用程序啟動時不加載不必要的組件,節省了內存,避免了針對不同業務形態的嵌入式系統生成不同版本的應用程序。[0091]總之,本發明實施例提出一種基于插件機制的動態加載組件方法,針對嵌入式系統的特點,只在具備組件功能的系統中以及在啟動組件功能時發現并加載組件,編譯時無需鏈接組件,從而無需為不同業務形態系統中是否需要該組件編譯生成不同版本。[0092]最后所應說明的是,以上實施例僅用以說明本發明的技術方案而非限制,盡管參照較佳實施例對本發明進行了詳細說明,本領域的普通技術人員應當理解,可以對本發明的技術方案進行修改或者等同替換,而不脫離本發明技術方案的精神和范圍。【權利要求】1.一種基于插件機制的動態加載組件方法,所述方法包含:步驟101)封裝組件庫;步驟102)當某個應用程序或組件收到需要調用另一個組件中具有某種功能的指令時,依據標識該另一組件身份的“MMEType”,遍歷系統中的各組件庫的“MMEType”進而查找所需組件;步驟103)當查找到所需組件后,在內存中加載所需組件,并獲取創建所需組件實例的接口以及調用所需組件的相應功能接口;其中,所有組件均具有唯一一個標識其身份的“MMEType”。2.根據權利要求2所述的基于插件機制的動態加載組件方法,其特征在于,所述步驟103)之后還包含:調用卸載組件接口,卸載加載的組件。3.根據權利要求1所述的基于插件機制的動態加載組件方法,其特征在于,采用插件標準NPAPI接口函數封裝組件庫。4.根據權利要求3所述的基于插件機制的動態加載組件方法,其特征在于,采用插件標準NPAPI接口函數封裝組件庫的方法具體包含如下步驟:在編譯組件庫的時候加入npruntime.h、np_entry.cpp、npn_gate.cpp、npp_gate.cpp以及設置插件調用接口的def文件;所述npruntime.h為頭文件,所述np_entry.cpp、npn_gate,cpp和npp_gate.cpp為接P函數,且接P函數np_entry.cpp、npn_gate.cpp和npp_gate,cpp定義在npruntime.h頭文件中;其中,np_entry.cpp中定義了三個接口,分別是:NP_GetEntryPoints-在插件加載之后立即調用該接口,用于瀏覽器獲取所有可能需要調用的API函數的指針;NP_Initialize-為插件提供全局初始化;NP_Shutdown-為插件提供全局反初始化;npn_gate.cpp文件用于實現20個函數接口,且這些接口是由瀏覽器實現的;在插件實例初始化的時候,將瀏覽器實現的這些函數的入口地址保存到一個NPNetscapeFuncs結構中,這些函數的實現就直接根據NPNetscapeFuncs結構中的入口地址調用瀏覽器實現的相關功能;且在開發插件時只需要調用NPN開頭的全局函數即可;npp_gate.cpp文件用于實現包含如下幾個函數接口:NPP_Shutdown():在卸載一個插件動態鏈接庫之前及刪除任何插件實例之后調用;NPP_New():在創建一個插件實例時調用,用于初始化插件的實例數據結構;NPP_Destroy():在刪除一個插件實例時調用,用于釋放為插件實例所分配的空間;NPP_GetMIMEDescript1nO:僅用于Unix環境,用于獲取由該插件所支持的MME類型;其中,Def文件用來設置插件供外部調用的接口,接口一般有三個,分別是NP_GetEntryPoints、NP_Initialize和NP_Shutdown;當組件庫完成封裝之后,如果某個應用程序或組件需要調用采用插件標準NPAPI接口函數封裝的組件庫的時候,通過調用NP_GetEntryPoints、NP_Initialize和NP_Shutdown這三個接口實現對組件庫方法的調用。5.根據權利要求4所述的基于插件機制的動態加載組件方法,其特征在于,瀏覽器在組件加載后調用NP_GetEntryPointS接口,獲取所有可能需要調用的API函數的指針,獲取的函數指針中就包含有NP_Initialize接口函數指針;然后調用NP_Initialize接口對組件進行全局初始化,初始化后獲得一系列NPN類和NPP類函數接口的指針,獲得的NPP類函數接口的指針中就包含有NPP_GetMIMEDescript1n接口函數指針;通過調用NPP_GetMIMEDescript1n接口函數,就能獲得該組件支持的“MMEType”。6.根據權利要求1所述的基于插件機制的動態加載組件方法,其特征在于,遍歷系統中各組件庫的特征接口進而查找所需組件;組件封裝之后,把封裝好的組件文件放在指定目錄下,當解析頁面遇到需要調用組件的方法時,加載所需組件;加載所需組件前,應用程序或組件首先遍歷系統中的各組件庫的"MIMEType”來查找所述組件,找到與指定所需組件的“MMEType”值相同的組件,進而加載所需組件。7.根據權利要求1所述的基于插件機制的動態加載組件方法,其特征在于,所述步驟103)進一步包含:加載組件時會調用NP_InitializeO進行初始化,初始化后獲得一系列NPN類和NPP類函數接口的指針,然后調用NPP_New()函數接口創建組件實例并初始化,實例對象的構造函數中會生成ScriptablePluginObject對象,創建組件實例后,當遇到需要調用組件中的方法,根據組件方法的名稱,去調用ScriptablePluginObject:HasMethod來判斷是否有這個方法,如果有這個方法,則會觸發ScriptablePluginObject::1nvoke函數運行,invoke函數內部根據方法名稱實現對應的操作。8.一種基于插件機制的動態加載組件的系統,其特征在于,所述系統包含:封裝模塊,用于把組件用插件標準NPAPI接口封裝,實現像調用標準插件那樣通過標準接口去查找組件并調用組件的方法;查找模塊,用于遍歷存放有多個組件庫的目錄,尋找到所需要調用的組件庫;和調用模塊,用于查找所需組件庫后去調用具體的方法實現相應的功能。【文檔編號】G06F9/445GK104424002SQ201310409594【公開日】2015年3月18日申請日期:2013年9月10日優先權日:2013年9月10日【發明者】胡琳琳,婁丙允,張武,郭志川申請人:中國科學院聲學研究所,北京中科海力技術有限公司