2

I have written a NPAPI plugin in C which needs to call the NPN_Invoke function (in order to call a JavaScript function).

But NPN_Invoke() takes the NPP instance as a parameter.

Only the NP_New() and NP_Destroy() functions get passed NPP instance. How do I get this NPP instance?

Thanks in advance.

DEzra
  • 2,978
  • 5
  • 31
  • 50

2 Answers2

2

The best way is actually to extend NPObject with a field to save the associated NPP instance, and provide the allocate/deallocate functions with your NPClass definition. You can then cast the NPObject to your subtype to access the actual NPP instance.

I would NOT recommend doing this at a global level (NP_GetEntryPoints, etc.) as suggested above, as there are potentially several instances of your plugin loaded - maybe even on the same page - and you want to be sure you're invoking the correct one. Unfortunately there seems to be a lot of sample code out there where some random instance is just kept in a global variable, and updated as much as possible.

As an example, assuming C++, you'll want to extend NPObject:

struct MyNPObject : public NPObject {
  NPP npp_;
  explicit MyNPObject(NPP npp) : npp_(npp) {}
};

Then your NPClass definition will need to have allocate and deallocate definitions:

static NPClass obj_Class = {
  NP_CLASS_STRUCT_VERSION,
  &obj_allocate,
  &obj_deallocate,
  NULL,
  &obj_hasMethod,
  &obj_invoke,
  ...

Which could be implemented like so:

static NPObject* obj_allocate(NPP npp, NPClass *aClass)
{
  return new MyNPObject(npp);
}

static void obj_deallocate(NPObject *obj)
{
  delete obj;
}

And when you need to call NP_Invoke, assuming you have the NPObject* (inside obj_invoke, for example) you just downcast:

MyNPObject* myObj = reinterpret_cast<MyNPObject*>(obj);
g_browser->invoke(myObj->npp, ...)
Dan Walters
  • 527
  • 4
  • 6
1

In the NP_GetEntryPoints define your own NP_yourNew Function, Now when the after the NP_New the framework calls your NP_yourNew with the instance. The instance could be saved when the your callback just gets invoked.

atVelu
  • 815
  • 1
  • 12
  • 24
  • You can find good examples of this in the mozilla codebase, under: mozilla-central/modules/plugin/sdk/samples/npruntime. You could also check out the FireBreath project (http://www.firebreath.org) for an example of a fully-implemented plugin framework. Start in np_winmain.cpp in one of the example projects and look at the src/NpapiPlugin project – taxilian Dec 02 '10 at 18:44