2

我用 C 编写了一个 NPAPI 插件,它需要调用NPN_Invoke函数(为了调用 JavaScript 函数)。

但是 NPN_Invoke() 将NPP实例作为参数。

只有 NP_New() 和 NP_Destroy() 函数才能通过 NPP 实例。我如何获得这个 NPP 实例?

提前致谢。

4

2 回答 2

2

最好的方法实际上是使用字段扩展 NPObject 以保存关联的 NPP 实例,并为您的 NPClass 定义提供分配/解除分配功能。然后,您可以将 NPObject 转换为您的子类型以访问实际的 NPP 实例。

建议按照上面的建议在全局级别(NP_GetEntryPoints 等)执行此操作,因为可能会加载您的插件的多个实例 - 甚至可能在同一页面上 - 并且您要确保调用正确的一。不幸的是,那里似乎有很多示例代码,其中一些随机实例只是保存在全局变量中,并尽可能地更新。

例如,假设 C++,您需要扩展 NPObject:

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

然后您的 NPClass 定义将需要分配和解除分配定义:

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

可以这样实现:

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

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

当您需要调用 NP_Invoke 时,假设您有 NPObject*(例如,在 obj_invoke 内部),您只需低调:

MyNPObject* myObj = reinterpret_cast<MyNPObject*>(obj);
g_browser->invoke(myObj->npp, ...)
于 2011-10-22T23:45:28.070 回答
1

在 NP_GetEntryPoints 中定义你自己的 NP_yourNew 函数,现在当 NP_New 之后框架用实例调用你的 NP_yourNew 时。当您的回调刚刚被调用时,可以保存该实例。

于 2009-06-24T11:22:43.090 回答