瀏覽器和js交互、NPAPI之NPRuntime開發

前面介紹過NPRuntime 

NPAPI 原本是由 Netscape 所制定的一組單純的 C Plugin API,起初是無法支持 Scriptability;於是到了 2004 年底,各家 Browser (IE, Opera, Mozilla 等) 都同意支持NPRuntime 延伸 API 以支持 Scriptability,所以目前若是想寫 Plugin則應該以 NPRuntime API 才能跨不同的 Browsers。

先介紹下瀏覽器的生命週期。


1.瀏覽器搜索加載DLL文件。

2.瀏覽器調用NP_GetEntryPoints,NP_Initialize()來初始化瀏覽器和插件的函數映射表。

i.調用瀏覽器端的NP_Initialize,將函數傳給插件的函數表。

  ii.插件將定義好的函數通過NP_GetEntryPoints,傳遞到NPPluginFuncs中,讓瀏覽器可以調用。

3.瀏覽器調用插件的NPP_GetValue,得到插件的對象,若支持js交互,則通過NPPVpluginScriptableNPObject來判斷創建m_pScriptableObject對象。

4.瀏覽器通過HTML中的MIMTYPE,調用插件的NP_New來創建插件實例。然後對插件進行業務處理。

5.瀏覽器關閉頁面時,調用插件的NPP_Destory來銷燬插件實例。

6.瀏覽器關閉時,調用NP_shutdown關閉所有的資源。

以上就是瀏覽器插件的生命週期。


下面來看下NPRuntime的執行過程。

瀏覽器調用插件的方法的順序,基本上爲:NP_GetEntryPointsNP_InitializeNPP_NewNPP_SetWindowNPP_GetValue。在NPP_New中,我們需要創建插件對象的實例,NPP_SetWindow中,瀏覽器會傳入插件窗口的信息,最後一個NPP_GetValue,是瀏覽器來獲取一些插件信息的。NPP_GetValue函數的結構是這樣的:

NPError  NPP_GetValue(NPP instance, NPPVariable variable, void *value);

· instance包含着插件對象實例;

· variable表示瀏覽器要獲取的信息的類型;

· value表示返回給瀏覽器的值


i.瀏覽器會傳入NPPVpluginScriptableNPObject(作爲variable參數)來查詢插件是否支持Scriptable功能(即和腳本語言交互的功能)

ii.可以利用NPN_CreateObject方法來創建一個NPObject對象,並且作爲value返回給瀏覽器。

iii.瀏覽器就通過這個NPObject對象和我們的插件建立了連接。

V.當頁面上JavaScript調用了我們插件對象的某個方法時,瀏覽器會調用該NPObject對象的HasMethod方法來查詢是否支持這個方法,

VI.如果支持,則會調用NPObject對象的Invoke方法,傳入方法名、參數等信息。

VII.這樣,我們就可以讓網頁上的腳本語言來執行我們編寫的函數了。

VIII.在Windows上,我們編寫的函數就如同編寫普通的應用程序一樣,可以使用很多Windows API來完成許多複雜的工作。

如下圖。


其中NPRuntime插件對象如下圖:

插件和js交互時,js調用插件的屬性和方法,調用getProperty,hasMethod,invoke方法即可。


如何定義一個方法(或屬性)?

1、添加一個方法(或屬性)很簡單,先定義一個靜態NPIdentifier類型的變量,例如:

static NPIdentifier s_idSetArgs;

2、在插件對象構造函數中,使用NPN_GetStringIdentifier方法來設置該方法的名稱,例如:

s_idSetArgs = NPN_GetStringIdentifier("SetArgs");

其中,SetArgs就是我們提供給腳本語言調用的方法名稱。

3、在ScriptablePluginObject的HasMethod方法中,判斷傳入的方法名:

[cpp] view plain copy
  1. bool ScriptablePluginObject::HasMethod(NPIdentifier name)  
  2. {  
  3.     char *pProp = NPN_UTF8FromIdentifier(name);  
  4.     //Check which Properties are available  
  5.     if( !strcmp( "Add", pProp ) )  
  6.     {  
  7.         return true;  
  8.     }  
  9.     if(name == s_idSetArgs)  
  10.     {  
  11.         printf("method name = SetArgs\n");  
  12.         return true;  
  13.     }  
  14.     return false;  
  15. }   

4.在Plugin的Invoke方法中,判斷如果傳入的方法名稱等於我們定義的方法名,則做你想要做得事情:

[cpp] view plain copy
  1. bool  
  2. ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)  
  3. {  
  4.     //kk      
  5.     char *pFunc = NPN_UTF8FromIdentifier(name);  
  6.           
  7.     if( !strcmp( "Add", pFunc ) )  
  8.     {  
  9.         int sum = 0;  
  10.   
  11.         for( unsigned int i = 0; i < argCount; i++ )  
  12.         {  
  13.             if( args[i].type == NPVariantType_Int32 )  
  14.             {  
  15.                 sum += args[i].value.intValue;  
  16.             }  
  17.             else if( args[i].type == NPVariantType_String )  
  18.             {  
  19.                 CNPString s(args[i].value.stringValue);  
  20.                 sum += atoi( s );  
  21.             }  
  22.             else   
  23.                 return false;//an error happenend  
  24.   
  25.         }  
  26.         //value for GUI output  
  27.         sprintf( m_szTextGui, "Sum = %ld", sum );  
  28.         //triggering  
  29.         ::InvalidateRect( m_hWnd, 0, true );  
  30.         //nice and handy little helpers, there are more of it   
  31.         INT32_TO_NPVARIANT( sum,*result);  
  32.         return true;  
  33.     }  
  34.         return false;  
  35. }  

在HTML中調用方法如下。

[html] view plain copy
  1. <embed type="application/npruntime" width=600 height=200 id="plugin">  

JS調用Add方法如下:

[javascript] view plain copy
  1. function Add()  
  2. {  
  3.     try  
  4.     {     
  5.         //if( CheckBrowser() ) return;  
  6.         var a1 = document.getElementById("f1").value;  
  7.         var a2 = document.getElementById("f2").value;  
  8.         alert("test");  
  9.         var res = PLUGIN.Add(a1,a2);//we can also add numbers and strings (because of the plugin implementation)  
  10.         alert( "Plugin Added result is: " + res );  
  11.     }  
  12.     catch (err) { alert(err); }  
  13. }  

這裏就可以JS和瀏覽器插件進行交互了。



轉自:http://blog.csdn.net/ec06cumt/article/details/12704169?utm_source=tuicool&utm_medium=referral

發佈了24 篇原創文章 · 獲贊 51 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章