最近项目中需要我编写跨平台的浏览器控件供JavaScript调用,经过几天折腾,我的插件已经能够很好的工作在Windows、Linux、Mac平台上的主流浏览器上,和JavaScript也可以很好的进行交互通知,下面就介绍一下主要的NPAPI插件开发流程和一些需要特别注意的地方。
- 下载NPAPI-SDK,里面有4个文件npapi.h、npfunctions.h、npruntime.h、nptypes.h,我们不需要改动它们。
- 在http://mxr.mozilla.org/seamonkey/source/modules/plugin/samples/npruntime/下载np_entry.cpp、npn_gate.cpp、npp_gate.cpp,我们需要利用它们实现插件脚本化支持。np_entry.cpp和npn_gate.cpp我们不用修改,最主要的就是npp_gate.cpp里面的这3个函数:NPP_GetMIMEDescription、NPP_New和NPP_GetValue,对于Windows版本的插件重要的还有NPP_SetWindow,我们将使用作为参数传进来的窗口句柄实现插件自己的消息循环,在和JavaScript进行通信的时候我们会使用到。
- 修改NPP_GetMIMEDescription,Linux版的插件必须实现该函数,返回值必须为指定的格式:
NP_GetMIMEDescription()
application/basic-plugin便是该插件的MIME TYPE了,每个NPAPI插件必须定义自己的的MIME TYPE,这样JavaScript就可以通过MIME TYPE加载插件了,Windows版的插件MIME TYPE是通过.rc资源文件里定义的"MIMEType"字段返回的,Mac版的插件则是通过Info.plist里的WebPluginMIMETypes字段返回的,具体可以参见NPAPI-SDK里的samples里面的例子。
{
return "application/basic-plugin:bsc:Basic plugin";
} - 我们需要在NPP_New里创建我们的插件实例,并使用instance->pdata保存,以便在其他NPP_*函数里可以使用我们的插件实例。另外Mac平台下需要设置NPPVpluginEventModel使用NPEventModelCocoa,否则Chrome浏览器无法正常加载插件。
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved)
{
if(instance->pdata == NULL)
instance->pdata = new CPlugin();
#ifdef XP_MACOSX
NPN_SetValue(instance, NPPVpluginEventModel, (void *)NPEventModelCocoa);
#endif
}