LIBRARY "" EXPORTS NP_GetEntryPoints @1 NP_Initialize @2 NP_Shutdown @3
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* aNPPFuncs) { return fillPluginFunctionTable(aNPPFuncs); }其调用的fillPluginFunctionTable为:
static NPError fillPluginFunctionTable(NPPluginFuncs* aNPPFuncs) { if (!aNPPFuncs) return NPERR_INVALID_FUNCTABLE_ERROR; // Set up the plugin function table that Netscape will use to call us. aNPPFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; aNPPFuncs->newp = NPP_New; aNPPFuncs->destroy = NPP_Destroy; aNPPFuncs->setwindow = NPP_SetWindow; aNPPFuncs->newstream = NPP_NewStream; aNPPFuncs->destroystream = NPP_DestroyStream; aNPPFuncs->asfile = NPP_StreamAsFile; aNPPFuncs->writeready = NPP_WriteReady; aNPPFuncs->write = NPP_Write; aNPPFuncs->print = NPP_Print; aNPPFuncs->event = NPP_HandleEvent; aNPPFuncs->urlnotify = NPP_URLNotify; aNPPFuncs->getvalue = NPP_GetValue; aNPPFuncs->setvalue = NPP_SetValue; return NPERR_NO_ERROR; }fillPluginFunctionTable函数设置了一系列的函数入口,都是很熟悉的在mozilla的开发文档中经常提到的以NPP开头的函数。这些函数是需要在插件中加以实现的。
NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs) { NPError rv = fillNetscapeFunctionTable(aNPNFuncs); if (rv != NPERR_NO_ERROR) return rv; return NS_PluginInitialize(); }其调用的fillNetscapeFunctionTable为:
static NPError fillNetscapeFunctionTable(NPNetscapeFuncs* aNPNFuncs) { if (!aNPNFuncs) return NPERR_INVALID_FUNCTABLE_ERROR; if (HIBYTE(aNPNFuncs->version) > NP_VERSION_MAJOR) return NPERR_INCOMPATIBLE_VERSION_ERROR; if (aNPNFuncs->size < sizeof(NPNetscapeFuncs)) return NPERR_INVALID_FUNCTABLE_ERROR; NPNFuncs.size = aNPNFuncs->size; NPNFuncs.version = aNPNFuncs->version; NPNFuncs.geturlnotify = aNPNFuncs->geturlnotify; NPNFuncs.geturl = aNPNFuncs->geturl; NPNFuncs.posturlnotify = aNPNFuncs->posturlnotify; NPNFuncs.posturl = aNPNFuncs->posturl; NPNFuncs.requestread = aNPNFuncs->requestread; NPNFuncs.newstream = aNPNFuncs->newstream; NPNFuncs.write = aNPNFuncs->write; NPNFuncs.destroystream = aNPNFuncs->destroystream; NPNFuncs.status = aNPNFuncs->status; NPNFuncs.uagent = aNPNFuncs->uagent; NPNFuncs.memalloc = aNPNFuncs->memalloc; NPNFuncs.memfree = aNPNFuncs->memfree; NPNFuncs.memflush = aNPNFuncs->memflush; NPNFuncs.reloadplugins = aNPNFuncs->reloadplugins; NPNFuncs.getvalue = aNPNFuncs->getvalue; NPNFuncs.setvalue = aNPNFuncs->setvalue; NPNFuncs.invalidaterect = aNPNFuncs->invalidaterect; NPNFuncs.invalidateregion = aNPNFuncs->invalidateregion; NPNFuncs.forceredraw = aNPNFuncs->forceredraw; return NPERR_NO_ERROR; }这里获取一系列函数的入口,这些函数是浏览器中实现的。
#ifndef npplat_h_ #define npplat_h_ #include "npapi.h" #include "npfunctions.h" #ifdef XP_WIN #include "windows.h" #endif #ifdef XP_UNIX #include <stdio.h> #endif #ifdef XP_MAC #include <Carbon/Carbon.h> #endif #ifndef HIBYTE #define HIBYTE(i) (i >> 8) #endif #ifndef LOBYTE #define LOBYTE(i) (i & 0xff) #endif #endif另外看看pluginbase.h,该文件定义了nsPluginInstanceBase类并声明了四个全局函数: NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)
NPError NPN_GetURL(NPP instance, const char *url, const char *target) { return (*NPNFuncs.geturl)(instance, url, target); }这个一看咱就明白了,NPN_GetURL确实可以说是浏览器实现的,因为这个函数直接调用了NPNetscapeFuncs的一个函数地址处的函数。
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的插件所有平台都可用 |