NPAPI is a set of APIs that allow you to create plugins for Firefox, Chrome, Safari, Opera. In this article I want to give initial information about the creation of a plug-in based on NPAPI. An example of a plug-in under Windows will be given, but the article will be useful for Mac and Unix developers as well. describes a general approach to creating plugins using NPAPI.
An NPAPI plugin is a module that “clings” to the browser and is responsible for handling a specific
content type (for example,
application / x-shockwave-flash ).
You can read about how NPAPI appeared and changed on the page in
WikipediaA full description of the API is available on the
Gecko_Plugin_API_Reference page
.First you need to download
XULRunner which includes the header files needed to create a plugin (
include \ plugin ). If you are working in Visual Studio - do not forget to add the path to the Include files in VC ++ Directories (
menu item Tools -> Options -> Projects and Solutions -> VC ++ Directories ).
')
The plugin is a module that exports the following functions:
NP_GetEntryPoints - called when the plug-in is loaded. Using this function, the browser receives pointers to other functions contained in the plugin that the browser needs to work with the plugin.
NP_Initialize - called when the plugin is initialized. When called, the browser sends pointers to its functions that the plugin may need.
NP_Shutdown - called when the plug-in is completed.
The order of calling
NP_GetEntryPoints and
NP_Initialize may vary depending on the browser. In particular, Chrome first calls
NP_GetEntryPoints , then
NP_Initialize .
Let's look at these features more closely.
NP_GetEntryPointsPrototype:NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs)
A pointer to the
NPPluginFuncs structure is passed as an argument
.typedef struct _NPPluginFuncs {
//
uint16_t size;
//
uint16_t version;
//
NPP_NewProcPtr newp;
//
NPP_DestroyProcPtr destroy;
// ,
// ( , ) ,
// , .
NPP_SetWindowProcPtr setwindow;
// .
NPP_NewStreamProcPtr newstream;
// .
NPP_DestroyStreamProcPtr destroystream;
// ,
// .
NPP_StreamAsFileProcPtr asfile;
// ,
// .
NPP_WriteReadyProcPtr writeready;
// .
NPP_WriteProcPtr write;
// ,
// .
NPP_PrintProcPtr print;
// .
NPP_HandleEventProcPtr event;
// URL .
NPP_URLNotifyProcPtr urlnotify;
// , .
void* javaClass;
// .
NPP_GetValueProcPtr getvalue;
// .
NPP_SetValueProcPtr setvalue;
} NPPluginFuncs;
The structure in addition to the size (
uint16_t size ) and version (
uint16_t version ) contains pointers to functions implemented by the plugin. Looking ahead a bit, I’ll say that
NPP_ is a prefix for functions implemented by the plugin, then we’ll come across functions starting with
NPN_ - these functions are implemented by the browser. It seems to be a trifle, but this knowledge helps to better understand the life cycle of the plugin.
Not all of the above functions can be used by the plugin, I have not found anywhere information on whether to assign NULL functions to unused functions, so I created stub functions that do nothing but return a value meaning success of the NPERR_NO_ERROR call. For example for
NPP_DestroyStreamProcPtr :
static NPError StubDestroyStream(NPP instance, NPStream *stream, NPReason reason)
{
return NPERR_NO_ERROR;
}
NP_InitializePrototype for Windows:NPError WINAPI NP_Initialize(NPNetscapeFuncs *aNPNFuncs)
Unix prototype:NPError NP_Initialize(NPNetscapeFuncs *aNPNFuncs, NPPluginFuncs *aNPPFuncs)
Called when the plugin is initialized. The function should be called by the browser only once, before creating the first instance of the plugin.
A pointer to the
NPNetscapeFuncs structure is passed as an argument
.typedef struct _NPNetscapeFuncs {
//
uint16_t size;
//
uint16_t version;
// GET
NPN_GetURLProcPtr geturl;
// POST
NPN_PostURLProcPtr posturl;
//
NPN_RequestReadProcPtr requestread;
//
NPN_NewStreamProcPtr newstream;
//
NPN_WriteProcPtr write;
//
NPN_DestroyStreamProcPtr destroystream;
//
NPN_StatusProcPtr status;
// "user agent"
NPN_UserAgentProcPtr uagent;
//
NPN_MemAllocProcPtr memalloc;
//
NPN_MemFreeProcPtr memfree;
//
NPN_MemFlushProcPtr memflush;
//
NPN_ReloadPluginsProcPtr reloadplugins;
NPN_GetJavaEnvProcPtr getJavaEnv;
NPN_GetJavaPeerProcPtr getJavaPeer;
// GET
NPN_GetURLNotifyProcPtr geturlnotify;
// POST
NPN_PostURLNotifyProcPtr posturlnotify;
//
NPN_GetValueProcPtr getvalue;
//
NPN_SetValueProcPtr setvalue;
//
NPN_InvalidateRectProcPtr invalidaterect;
//
NPN_InvalidateRegionProcPtr invalidateregion;
// ,
NPN_ForceRedrawProcPtr forceredraw;
//
NPN_GetStringIdentifierProcPtr getstringidentifier;
//
NPN_GetStringIdentifiersProcPtr getstringidentifiers;
//
NPN_GetIntIdentifierProcPtr getintidentifier;
//
NPN_IdentifierIsStringProcPtr identifierisstring;
//
NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;
//
NPN_IntFromIdentifierProcPtr intfromidentifier;
//
NPN_CreateObjectProcPtr createobject;
//
NPN_RetainObjectProcPtr retainobject;
//
NPN_ReleaseObjectProcPtr releaseobject;
//
NPN_InvokeProcPtr invoke;
//
NPN_InvokeDefaultProcPtr invokeDefault;
//
NPN_EvaluateProcPtr evaluate;
//
NPN_GetPropertyProcPtr getproperty;
//
NPN_SetPropertyProcPtr setproperty;
//
NPN_RemovePropertyProcPtr removeproperty;
//
NPN_HasPropertyProcPtr hasproperty;
//
NPN_HasMethodProcPtr hasmethod;
// , NPVariant
NPN_ReleaseVariantValueProcPtr releasevariantvalue;
//
NPN_SetExceptionProcPtr setexception;
NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
//
NPN_EnumerateProcPtr enumerate;
//
NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
//
NPN_ConstructProcPtr construct;
NPN_GetValueForURLPtr getvalueforurl;
NPN_SetValueForURLPtr setvalueforurl;
NPN_GetAuthenticationInfoPtr getauthenticationinfo;
} NPNetscapeFuncs;
NP_ShutdownPrototype for Windows:void WINAPI NP_Shutdown(void);
Unix prototype:void NP_Shutdown(void);
Called when the plugin is unloaded. In this function, the plugin should free the allocated memory, destroy the created objects, etc. This function is called last, after all instances of the plugin have been removed.
To create a plugin, you need to create a DLL, implement the listed exported functions, and you can start experimenting. One important note is that the plugin will not be loaded by the browser if its version information does not
contain the MIMEType string that defines the
content type that the plugin processes. In the resource file, it looks like this:
VALUE "MIMEType", "application/minimize-to-tray-extension"
Without this line, Chrome did not want to load the plugin, and for a long time I could not understand why DllMain was not called, let alone other exported functions.
To save yourself from the implementation of all the functions that the plugin should have, as a starting point you can take the source code of my Google Chrome extension project
Minimize to tray