<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                要理解PPAPI插件的設計,先仔細閱讀下面這些文章: - [**Chromium的Process Models**](http://www.chromium.org/developers/design-documents/process-models) - [**Chromium的Multi-process Architecture**](http://www.chromium.org/developers/design-documents/multi-process-architecture) - [**Chromium的Plugin Architecture**](http://www.chromium.org/developers/design-documents/plugin-architecture) - [**Pepper plugin implementation**](http://www.chromium.org/developers/design-documents/pepper-plugin-implementation) 理解了架構設計,再看代碼層面的文檔: - [**Important concepts for working with PPAPI**](https://code.google.com/p/ppapi/wiki/Concepts) - [**GettingStarted, Writing a simple plugin**](https://code.google.com/p/ppapi/wiki/GettingStarted) 有的鏈接需要翻墻,天朝的局域網,我愛死你了。 好啦,現在對PPAPI應該有基本的理解了。接下來我從代碼角度來理解一下。 # Module、Instance、Interface HTML頁面可以通過embed標簽來嵌入一個插件,HTML頁面被加載時,解析到embed標簽,就會根據type屬性定位我們注冊的PPAPI插件,加載對應的插件庫(DLL)。 當PPAPI的庫文件(DLL)被加載到瀏覽器進程中時,一個Module就產生了。在代碼中,通過PP_Module(定義在pp_module.h中)來表示,用于標識一個Module的PP_Module類型實際上是一個int32。Module的標識符通過PPP_InitializeModule函數傳入。PPP_InitializeModule函數的原型如下: ~~~ int32_t PPP_InitializeModule(PP_Module module, PPB_GetInterface get_browser_interface) ; ~~~ 第一個參數就是瀏覽器分配給你的插件庫文件的標識符(handle),一般你需要保存它,后續的有些API會用到。 所以,一個Module,僅僅標識了library。要想在瀏覽器上顯示點什么,還需要從這個Module里創建一個實例,這個實例代表了我們可以看見并與之交互的網頁對象。一個插件實例對象又有兩個層面的屬性,一個就是標示符,通過PP_Instance(32位整型)來表示;另外一個是用來操作實例對象的接口,用PPP_Instance表示(聚合了各種函數指針的結構體)。 PPAPI的plugin會導出PPP_GetInterface函數,其原型如下: ~~~ const void* PPP_GetInterface(const char* interface_name); ~~~ 當瀏覽器要為HTML頁面創建插件實例時,會先調用PPP_GetInterface函數獲取一個實例模板指針(可以理解為PPP_Instance的實例,類似一個類,實際上是一個定義了函數指針成員的結構體)。 PPP_GetInterface函數接受一個字符串名字,返回void*,瀏覽器拿到萬能的void*后會根據名字轉換為具體的PPP_instance接口,在后續使用中就通過PPP_instance接口來與插件實例交互(比如具體的創建、銷毀等動作)。 簡單的理解,就是PPP_GetInterface會返回能創建Instance的接口PPP_Instance,瀏覽器調用PPP_Instance來創建實例并與實例交互。 PPP_instance接口聲明如下: ~~~ struct PPP_Instance_1_1 { PP_Bool (*DidCreate)(PP_Instance instance, uint32_t argc, const char* argn[], const char* argv[]); void (*DidDestroy)(PP_Instance instance); void (*DidChangeView)(PP_Instance instance, PP_Resource view); void (*DidChangeFocus)(PP_Instance instance, PP_Bool has_focus); PP_Bool (*HandleDocumentLoad)(PP_Instance instance, PP_Resource url_loader); }; ~~~ 如你所見,它就像一個類,DidCreate是構造函數指針,DidDestroy是析構函數指針。創建插件實例對象時,DidCreate會被調用,其第一個參數instance,就是瀏覽器分配給這個插件實例對象的句柄(32位整數),通常我們可以保存起來供后續的調用使用。具體的說明,可以看ppp_instance.h。 之前在[**VS2013編譯最簡單的PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485461)中我們編譯了stub插件,它的PPP_GetInterface函數返回NULL,所以,其實瀏覽器可以加載stub庫文件,生成Module,但無法創建Instance。 要想實作一個有用的PPAPI plugin,必須在PPP_GetInterface中返回真實的PPP_instance接口。下面是graphics_2d_example.c里的PPP_GetInterface函數實現: ~~~ PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) return &instance_interface; return NULL; } ~~~ 它返回的instance_interface,是這么定義的: ~~~ static PPP_Instance instance_interface = { &Instance_DidCreate, &Instance_DidDestroy, &Instance_DidChangeView, &Instance_DidChangeFocus, &Instance_HandleDocumentLoad }; ~~~ 如你所見,它是一個PPP_Instance,在定義時進行了初始化,把文件內實現的幾個函數,賦值給了結構體的5個函數指針。 # 瀏覽器接口PPB_GetInterface PPAPI插件要與瀏覽器交互,也得先有渠道來獲取瀏覽器的功能接口。瀏覽器提供了很多功能接口,比如PPB_INSTANCE_INTERFACE,PPB_IMAGEDATA_INTERFACE,PPB_GRAPHICS_2D_INTERFACE等。 這些宏都是字符串,瀏覽器提供的接口名字宏,以PPB_開頭,插件提供的,以PPP_開頭。 插件被加載時,模塊初始化函數PPP_InitializeModule會被調用,其原型如下: ~~~ int32_t PPP_InitializeModule(PP_Module module_id, PPB_GetInterface get_browser_interface); ~~~ 注意第二個參數,get_browser_interface,它的類型是PPB_GetInterface,是一個函數指針,定義如下: ~~~ typedef const void* (*PPB_GetInterface)(const char* interface_name); ~~~ 如你所見,這是一個接受一個字符串參數返回void*的函數指針。插件可以在PPP_InitializeModule被調用時保存第一個參數,用它來獲取瀏覽器提供的各種接口。根據接口名字,把返回的void*強制轉換為對應的接口來使用。參看graphics_2d_example.c里的實現: ~~~ PP_EXPORT int32_t PPP_InitializeModule(PP_Module module, PPB_GetInterface get_browser_interface) { g_get_browser_interface = get_browser_interface; g_core_interface = (const PPB_Core*) get_browser_interface(PPB_CORE_INTERFACE); g_instance_interface = (const PPB_Instance*) get_browser_interface(PPB_INSTANCE_INTERFACE); g_image_data_interface = (const PPB_ImageData*) get_browser_interface(PPB_IMAGEDATA_INTERFACE); g_graphics_2d_interface = (const PPB_Graphics2D*) get_browser_interface(PPB_GRAPHICS_2D_INTERFACE); g_view_interface = (const PPB_View*) get_browser_interface(PPB_VIEW_INTERFACE); if (!g_core_interface || !g_instance_interface || g_image_data_interface || !g_graphics_2d_interface || !g_view_interface) return -1; return PP_OK; } ~~~ 當我們拿到了瀏覽器暴露的各種接口,就可以做想干的事情了。 對于PPAPI插件的設計,先理解到這里,下次我們看插件的加載與使用流程、如何繪圖、如何處理交互。 相關文章參考: - [**CEF Windows開發環境搭建**](http://blog.csdn.net/foruok/article/details/50468642) - [**CEF加載PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485448) - [**VS2013編譯最簡單的PPAPI插件**](http://blog.csdn.net/foruok/article/details/50485461)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看