前面介紹過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_GetEntryPoints、NP_Initialize、NPP_New、NPP_SetWindow、NPP_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方法中,判斷傳入的方法名:
- bool ScriptablePluginObject::HasMethod(NPIdentifier name)
- {
- char *pProp = NPN_UTF8FromIdentifier(name);
- //Check which Properties are available
- if( !strcmp( "Add", pProp ) )
- {
- return true;
- }
- if(name == s_idSetArgs)
- {
- printf("method name = SetArgs\n");
- return true;
- }
- return false;
- }
4.在Plugin的Invoke方法中,判斷如果傳入的方法名稱等於我們定義的方法名,則做你想要做得事情:
- bool
- ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
- {
- //kk
- char *pFunc = NPN_UTF8FromIdentifier(name);
- if( !strcmp( "Add", pFunc ) )
- {
- int sum = 0;
- for( unsigned int i = 0; i < argCount; i++ )
- {
- if( args[i].type == NPVariantType_Int32 )
- {
- sum += args[i].value.intValue;
- }
- else if( args[i].type == NPVariantType_String )
- {
- CNPString s(args[i].value.stringValue);
- sum += atoi( s );
- }
- else
- return false;//an error happenend
- }
- //value for GUI output
- sprintf( m_szTextGui, "Sum = %ld", sum );
- //triggering
- ::InvalidateRect( m_hWnd, 0, true );
- //nice and handy little helpers, there are more of it
- INT32_TO_NPVARIANT( sum,*result);
- return true;
- }
- return false;
- }
在HTML中調用方法如下。
- <embed type="application/npruntime" width=600 height=200 id="plugin">
JS調用Add方法如下:
- function Add()
- {
- try
- {
- //if( CheckBrowser() ) return;
- var a1 = document.getElementById("f1").value;
- var a2 = document.getElementById("f2").value;
- alert("test");
- var res = PLUGIN.Add(a1,a2);//we can also add numbers and strings (because of the plugin implementation)
- alert( "Plugin Added result is: " + res );
- }
- catch (err) { alert(err); }
- }
這裏就可以JS和瀏覽器插件進行交互了。
轉自:http://blog.csdn.net/ec06cumt/article/details/12704169?utm_source=tuicool&utm_medium=referral