浏览器和js交互、NPAPI之NPRuntime开发

来源:互联网 发布:自助建站系统源码 编辑:程序博客网 时间:2024/05/16 12:06

前面介绍过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

0 0
原创粉丝点击