npapi总结--发文于2013-12-13
2016-01-15 22:48
309 查看
一个插件中的方法分为插件方法(Plug-in Methods)和浏览器方法(Browser Methods)。
插件方法是你在插件中自己去执行的那些方法,以NPP为前缀命名。
浏览器方法是被Gecko所执行的那些方法,以NPN为前缀命名。数据结构(Data Structures)以NP开头。
extension可以和web页面交互,或者通过content script 或者cross-original XMLHttpRequests与服务器交互。
extension还可以访问浏览器提供的内部功能,例如标签或者书签等。
几个关键接口的调用顺序.
NP_GetEntryPoints====> 在插件加载之后立即调用该接口,用于浏览器获取所有可能需要调用的API函数的指针。插件用NPP_New, NPP_Destroy, NPP_SetWindow等函数的入口地址填充一个函数表。
NP_Initialize ====>被载入内存时,全局初始化,初始化浏览器实现的函数.插件存储一个NPN_CreateObject, NPN_MemAlloc,等函数入口地址组成的函数表的拷贝。
NPP_New ====> 浏览器插件实例化时,创建插件对象实例. 插件创建一个新的插件实例并初始化
NPP_SetWindow ====> 建立窗口时,浏览器传入插件窗口信息.每个实例都会多次调用这个函数——每次实例窗口创建、改变大小或者其他变化都会调用。
NPP_GetValue ====> 设置NPObject对象时,浏览器用来获取插件信息. 插件创建一个支持脚本的NPObject并返回其指针(调用NPN_RetainObject)。
— 标准的插件活动 —
NPP_Destroy ====> 插件销毁内存实例
NP_Shutdown ====>最后一个插件实例被销毁时,反初始化
np_entry.cpp文件中可以找到上面的几个函数。
与js的交互方法, 主要依赖的是NPObject对象, 该对象的NPClass成员携带的是处理js交互的方法:
NPAllocateFunctionPtr ==> 生成此NPClass对象的方法
NPDeallocateFunctionPtr ==> 销毁此NPClass对象的方法
NPHasMethodFunctionPtr ==> 检查获取的id是否是想要处理的
NPInvokeFunctionPtr ==> 在上个函数设置为需要处理时, 会调用此函数
NPInvokeDefaultFunctionPtr ==> 默认被调用的函数
NPHasPropertyFunctionPtr ==>
NPGetPropertyFunctionPtr ==>
NPSetPropertyFunctionPtr ==>
插件的加载过程:
当一个页面打开时,如果该页面上有嵌入一个插件,浏览器将会做以下事情:
通过MIMEType检查是否有匹配插件
加载插件代码到内存
初始化插件
创建一个新的插件实例
插件可以在一个页面上被实例多个对象,也可以在同一时刻在不同的窗口中被实例化。当页面被关闭时,插件的实例就会被销毁。当最后一个实例被删除后,插件代码就会从内存中被卸载掉。
下面是插件内的函数调用过程:
如果插件是首次被载入内存,浏览器会调用插件的NP_Initialize方法。为了方便起见,所有的插件定义函数以“NPP”开头,所有的浏览器定义函数以“NPN”开头。
当浏览器创建插件实例时,会调用NPP_New方法。
当插件实例被删除时(如关闭页面、关闭窗口),会调用NPP_Destroy方法。
当最后一个实例被删除,插件从内存中卸载时,会调用NP_Shutdown方法
浏览器会传入NPPVpluginScriptableNPObject(作为variable参数)来查询插件是否支持Scriptable功能(即和脚本语言交互的功能),在这里,我们可以利用NPN_CreateObject方法来创建一个NPObject对象,并且作为value返回给浏览器。这样,浏览器就通过这个NPObject对象和我们的插件建立了连接。当页面上Javascript调用了我们插件对象的某个方法时,浏览器会调用该NPObject对象的HasMethod方法来查询是否支持这个方法,如果支持,则会调用NPObject对象的Invoke方法,传入方法名、参数等信息。这样,我们就可以让网页上的脚本语言来执行我们编写的函数了。在Windows上,我们编写的函数就如同编写普通的应用程序一样,可以使用很多Windows
API来完成许多复杂的工作。
plugin创建时,浏览器会创建一个子窗口,作为plugin的窗口(对于有窗口的plugin)。
对于windowed的plugin确实是窗口的句柄,而对于winless的plugin,window成员是一个HDC。因此,如果是winless的plugin,可以直接将pNPWindow->window强制转换为HDC然后在窗口中进行绘制、输出内容。
插件分为winless和windowed的,其主要区别是winless的插件窗口不是真正意义上的窗口只是网页的一部分,而windowed的插件窗口是浏览器的一个子窗口。由于winless的插件没有窗口所以其事件处理有一个专门的函数NPP_HandleEvent来对窗口的事件进行处理。对于winless的插件,事件响应函数就需要继承nsPluginInstanceBase类并实现函数HandleEvent;而对于windowed 的插件,插件窗口完全由插件控制,因此需要根据这个窗口句柄自行在插件中实现各种功能,包括事件消息响应等等。
npn_gate.cpp:在插件实例初始化的时候,将浏览器实现的这些函数的入口地址保存到一个NPNetscapeFuncs结构中,NPN_开头的这些函数名其实是开发插件时需要由开发者定义的,这些函数的实现就直接根据NPNetscapeFuncs结构中的入口地址调用浏览器实现的相关功能。但这些基本都是固定不变的,因此sdk中已经帮我们开发者写好了这些代码,在开发插件时只需要调用NPN_开头的全局函数即可。
NPP接口函数
可能调用的nsPluginInstanceBase成员函数或全局函数
备注
NPP_New
NS_NewPluginInstance
创建插件实例
NPP_Destroy
NS_DestroyPluginInstance、plugin->shut
删除插件实例
NPP_SetWindow
plugin->SetWindow、plugin->isInitialized、plugin->init、NS_DestroyPluginInstance
窗口创建、移动、改变大小或销毁时调用
NPP_NewStream
plugin->NewStream
通知插件实例有新的数据流
NPP_WriteReady
plugin->WriteReady
确定插件是否准备好接收数据(以及其准备接收的最大字节数)
NPP_Write
plugin->Write
调用以将数据读入插件this might be better named “NPP_DataArrived”
NPP_DestroyStream
plugin->DestroyStream
通知插件实例数据流将要关闭或销毁
NPP_StreamAsFile
plugin->StreamAsFile
为创建流数据提供本地文件名
NPP_Print
plugin->Print
为嵌入或全屏插件请求平台特定的打印操作
NPP_URLNotify
plugin->URLNotify
通知插件已完成URL请求
NPP_GetValue
plugin->GetValue
调用以查询插件信息(还用来获取NPObject/Scriptable 插件的实例)
NPP_SetValue
plugin->SetValue
这是用来为浏览器提供插件变量信息的
NPP_HandleEvent
plugin->HandleEvent
事件处理函数,对windowed的插件只在MAC操作系统上可用,对于winless的插件所有平台都可用
插件方法是你在插件中自己去执行的那些方法,以NPP为前缀命名。
浏览器方法是被Gecko所执行的那些方法,以NPN为前缀命名。数据结构(Data Structures)以NP开头。
extension可以和web页面交互,或者通过content script 或者cross-original XMLHttpRequests与服务器交互。
extension还可以访问浏览器提供的内部功能,例如标签或者书签等。
几个关键接口的调用顺序.
NP_GetEntryPoints====> 在插件加载之后立即调用该接口,用于浏览器获取所有可能需要调用的API函数的指针。插件用NPP_New, NPP_Destroy, NPP_SetWindow等函数的入口地址填充一个函数表。
NP_Initialize ====>被载入内存时,全局初始化,初始化浏览器实现的函数.插件存储一个NPN_CreateObject, NPN_MemAlloc,等函数入口地址组成的函数表的拷贝。
NPP_New ====> 浏览器插件实例化时,创建插件对象实例. 插件创建一个新的插件实例并初始化
NPP_SetWindow ====> 建立窗口时,浏览器传入插件窗口信息.每个实例都会多次调用这个函数——每次实例窗口创建、改变大小或者其他变化都会调用。
NPP_GetValue ====> 设置NPObject对象时,浏览器用来获取插件信息. 插件创建一个支持脚本的NPObject并返回其指针(调用NPN_RetainObject)。
— 标准的插件活动 —
NPP_Destroy ====> 插件销毁内存实例
NP_Shutdown ====>最后一个插件实例被销毁时,反初始化
np_entry.cpp文件中可以找到上面的几个函数。
与js的交互方法, 主要依赖的是NPObject对象, 该对象的NPClass成员携带的是处理js交互的方法:
NPAllocateFunctionPtr ==> 生成此NPClass对象的方法
NPDeallocateFunctionPtr ==> 销毁此NPClass对象的方法
NPHasMethodFunctionPtr ==> 检查获取的id是否是想要处理的
NPInvokeFunctionPtr ==> 在上个函数设置为需要处理时, 会调用此函数
NPInvokeDefaultFunctionPtr ==> 默认被调用的函数
NPHasPropertyFunctionPtr ==>
NPGetPropertyFunctionPtr ==>
NPSetPropertyFunctionPtr ==>
插件的加载过程:
当一个页面打开时,如果该页面上有嵌入一个插件,浏览器将会做以下事情:
通过MIMEType检查是否有匹配插件
加载插件代码到内存
初始化插件
创建一个新的插件实例
插件可以在一个页面上被实例多个对象,也可以在同一时刻在不同的窗口中被实例化。当页面被关闭时,插件的实例就会被销毁。当最后一个实例被删除后,插件代码就会从内存中被卸载掉。
下面是插件内的函数调用过程:
如果插件是首次被载入内存,浏览器会调用插件的NP_Initialize方法。为了方便起见,所有的插件定义函数以“NPP”开头,所有的浏览器定义函数以“NPN”开头。
当浏览器创建插件实例时,会调用NPP_New方法。
当插件实例被删除时(如关闭页面、关闭窗口),会调用NPP_Destroy方法。
当最后一个实例被删除,插件从内存中卸载时,会调用NP_Shutdown方法
浏览器会传入NPPVpluginScriptableNPObject(作为variable参数)来查询插件是否支持Scriptable功能(即和脚本语言交互的功能),在这里,我们可以利用NPN_CreateObject方法来创建一个NPObject对象,并且作为value返回给浏览器。这样,浏览器就通过这个NPObject对象和我们的插件建立了连接。当页面上Javascript调用了我们插件对象的某个方法时,浏览器会调用该NPObject对象的HasMethod方法来查询是否支持这个方法,如果支持,则会调用NPObject对象的Invoke方法,传入方法名、参数等信息。这样,我们就可以让网页上的脚本语言来执行我们编写的函数了。在Windows上,我们编写的函数就如同编写普通的应用程序一样,可以使用很多Windows
API来完成许多复杂的工作。
plugin创建时,浏览器会创建一个子窗口,作为plugin的窗口(对于有窗口的plugin)。
对于windowed的plugin确实是窗口的句柄,而对于winless的plugin,window成员是一个HDC。因此,如果是winless的plugin,可以直接将pNPWindow->window强制转换为HDC然后在窗口中进行绘制、输出内容。
插件分为winless和windowed的,其主要区别是winless的插件窗口不是真正意义上的窗口只是网页的一部分,而windowed的插件窗口是浏览器的一个子窗口。由于winless的插件没有窗口所以其事件处理有一个专门的函数NPP_HandleEvent来对窗口的事件进行处理。对于winless的插件,事件响应函数就需要继承nsPluginInstanceBase类并实现函数HandleEvent;而对于windowed 的插件,插件窗口完全由插件控制,因此需要根据这个窗口句柄自行在插件中实现各种功能,包括事件消息响应等等。
npn_gate.cpp:在插件实例初始化的时候,将浏览器实现的这些函数的入口地址保存到一个NPNetscapeFuncs结构中,NPN_开头的这些函数名其实是开发插件时需要由开发者定义的,这些函数的实现就直接根据NPNetscapeFuncs结构中的入口地址调用浏览器实现的相关功能。但这些基本都是固定不变的,因此sdk中已经帮我们开发者写好了这些代码,在开发插件时只需要调用NPN_开头的全局函数即可。
NPP接口函数
可能调用的nsPluginInstanceBase成员函数或全局函数
备注
NPP_New
NS_NewPluginInstance
创建插件实例
NPP_Destroy
NS_DestroyPluginInstance、plugin->shut
删除插件实例
NPP_SetWindow
plugin->SetWindow、plugin->isInitialized、plugin->init、NS_DestroyPluginInstance
窗口创建、移动、改变大小或销毁时调用
NPP_NewStream
plugin->NewStream
通知插件实例有新的数据流
NPP_WriteReady
plugin->WriteReady
确定插件是否准备好接收数据(以及其准备接收的最大字节数)
NPP_Write
plugin->Write
调用以将数据读入插件this might be better named “NPP_DataArrived”
NPP_DestroyStream
plugin->DestroyStream
通知插件实例数据流将要关闭或销毁
NPP_StreamAsFile
plugin->StreamAsFile
为创建流数据提供本地文件名
NPP_Print
plugin->Print
为嵌入或全屏插件请求平台特定的打印操作
NPP_URLNotify
plugin->URLNotify
通知插件已完成URL请求
NPP_GetValue
plugin->GetValue
调用以查询插件信息(还用来获取NPObject/Scriptable 插件的实例)
NPP_SetValue
plugin->SetValue
这是用来为浏览器提供插件变量信息的
NPP_HandleEvent
plugin->HandleEvent
事件处理函数,对windowed的插件只在MAC操作系统上可用,对于winless的插件所有平台都可用
相关文章推荐
- Android Manifest 用法
- Android学习笔记(二九):嵌入浏览器
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- java自动生成验证码插件-kaptcha
- 小白观察:微软释放出其基于 Chromium 的 Edge 浏览器
- 浏览器 cookie 限制
- jQuery菜单插件用法实例
- 玩转浏览器IE7的5个顶级使用技巧
- 字符集导致的浏览器跨站脚本攻击分析
- 加载flash9.ocx出现错误的解决方法
- 更改IE浏览器的图标
- jquery实现的代替传统checkbox样式插件
- 如何创建ajax对象并兼容多个浏览器
- css ie6 ie7 ff的CSS hack使用技巧
- CSS 浏览器的等宽空格问题解决
- 区分IE6,IE7,firefox的CSS hack
- 10款新鲜出炉的 jQuery 插件(Ajax 插件,有幻灯片、图片画廊、菜单等)