【发布时间】:2009-04-16 13:24:23
【问题描述】:
我用 C 语言编写了一个 NPAPI 插件,它需要调用 NPN_Invoke 函数 (为了调用 JavaScript 函数)。
但是 NPN_Invoke() 将 NPP 实例作为参数。
只有 NP_New() 和 NP_Destroy() 函数可以通过 NPP 实例。如何获取这个 NPP 实例?
提前致谢。
【问题讨论】:
我用 C 语言编写了一个 NPAPI 插件,它需要调用 NPN_Invoke 函数 (为了调用 JavaScript 函数)。
但是 NPN_Invoke() 将 NPP 实例作为参数。
只有 NP_New() 和 NP_Destroy() 函数可以通过 NPP 实例。如何获取这个 NPP 实例?
提前致谢。
【问题讨论】:
最好的方法实际上是用一个字段扩展 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, ...)
【讨论】:
在 NP_GetEntryPoints 中定义你自己的 NP_yourNew 函数,现在当 NP_New 之后框架用实例调用你的 NP_yourNew 时。当您的回调刚刚被调用时,可以保存该实例。
【讨论】: