我正在编写一个包含两种插件类型的NPAPI插件:
我有以下使用插件的HTML / JavaScript代码:
<html>
<embed id="display" type="application/x-display" width=640 height=480 /></td>
<embed id="capture" type="application/x-capture" width=0 height=0 /><br> <!-- windowless plugin -->
<script>
var capture = document.getElementById('capture');
var display = document.getElementById('display');
capture.addDisplay(display);
</script>
</html>
我的问题是我的库中addDisplay的调用接收一个不同的NPObject指针作为调用参数,然后是与提供的x-display实例相关联的指针。 此外,收到的NPObject结构的_class成员与我在创建x-display脚本对象时提供的成员不同。
在尝试枚举接收到的对象的方法(来自handleAddDisplay函数)以找到有关接收参数类型的更多信息后,我得到了一个包含nsJSObjWrapper的调用堆栈(我在Firefox / Windows上测试它)。我的库是npCaptureDemoPlugin.dll。最后,包装器调用显示对象的枚举。
npCaptureDemoPlugin.dll!RendererPlugin::hasMethod(void * name=0x06311d00) Line 84 C++
npCaptureDemoPlugin.dll!ScriptableObject<RendererPlugin>::Class::hasMethod(NPObject* object=0x191fd0b4, void * name=0x06311d00) Line 382 + 0x43 bytes C++
xul.dll!NPObjWrapper_NewResolve(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c4c0, int id=0x06311d00, unsigned int flags=0x00000001, JSObject * * objp=0x003cb838) Line 1659 C++
mozjs.dll!CallResolveOp(JSContext * cx=0x13bf8f60, JSObject * start=0x0650c4a0, JS::Handle<JSObject *> obj={...}, JS::Handle<int> id={...}, unsigned int flags=0x00000000, JSObject * * objp=0x003cb8dc, JSProperty * * propp=0x003cb8d4, bool * recursedp=0x003cb883) Line 4637 + 0x1b bytes C++
mozjs.dll!js_LookupProperty(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c4a0, int id=0x06311d00, JSObject * * objp=0x003cb8dc, JSProperty * * propp=0x003cb8d4) Line 4745 + 0x7a bytes C++
mozjs.dll!JS_LookupPropertyById(JSContext * cx=0x00000000, JSObject * obj=0x0650c4a0, int id=0x06311d00, JS::Value * vp=0x003cb8e4) Line 3502 + 0x49 bytes C++
xul.dll!xpc_ForcePropertyResolve(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c4a0, int id=0x06311d00) Line 652 + 0x13 bytes C++
xul.dll!XPC_WN_Shared_Enumerate(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c4a0) Line 605 + 0xe bytes C++
xul.dll!XPC_WN_JSOp_Enumerate(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c4a0, JSIterateOp enum_op=JSENUMERATE_INIT, JS::Value * statep=0x003cbaf4, int * idp=0x00000000) Line 1275 + 0x1b bytes C++
mozjs.dll!Snapshot(JSContext * cx=0x00000000, JSObject * obj=0x00000000, unsigned int flags=0x00000008, JS::AutoIdVector * props=0x003cbb78) Line 364 + 0x25 bytes C++
mozjs.dll!js::GetPropertyNames(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c4a0, unsigned int flags=0x00000008, JS::AutoIdVector * props=0x003cbb78) Line 440 + 0x1a bytes C++
mozjs.dll!JS_Enumerate(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c4a0) Line 4241 + 0x34 bytes C++
xul.dll!nsJSObjWrapper::NP_Enumerate(NPObject * npobj=0x089cbd90, void * * * idarray=0x003cbf74, unsigned int * count=0x003cbf68) Line 968 + 0xe bytes C++
xul.dll!mozilla::plugins::parent::_enumerate(_NPP * npp=0x10eff7c8, NPObject * npobj=0x089cbd90, void * * * identifier=0x003cbf74, unsigned int * count=0x003cbf68) Line 1900 + 0xc bytes C++
npCaptureDemoPlugin.dll!NPN_Enumerate(_NPP * npp=0x10eff7c8, NPObject * obj=0x089cbd90, void * * * identifier=0x003cbf74, unsigned int * count=0x003cbf68) Line 254 + 0x18 bytes C++
npCaptureDemoPlugin.dll!CapturePlugin::handleAddDisplay(NPObject * object=0x089cbd90) Line 382 + 0x18 bytes C++
npCaptureDemoPlugin.dll!CapturePlugin::invoke(void * name=0x13855280, const _NPVariant * args=0x003cc270, unsigned int argCount=0x00000001, _NPVariant * result=0x003cc248) Line 142 + 0xf bytes C++
npCaptureDemoPlugin.dll!ScriptableObject<CapturePlugin>::Class::invoke(NPObject * object=0x191feb04, void * name=0x13855280, const _NPVariant * args=0x003cc270, unsigned int argCount=0x00000001, _NPVariant * result=0x003cc248) Line 414 + 0x4f bytes C++
xul.dll!CallNPMethodInternal(JSContext * cx=0x13bf8f60, JSObject * obj=0x0650c3a0, unsigned int argc=0x00000001, JS::Value * argv=0x05cd0070, JS::Value * rval=0x05cd0060, bool ctorCall=false) Line 1482 + 0x11 bytes C++
所以它看起来像Firefox将我的NPObject包装到另一个我无法处理的NPObject中,这个NPObject被用作调用我的对象的代理。
我的问题:有没有办法将相同的NPObject传递给函数调用,就像我与插件实例相关联的那样?或者是否有另一种方法来检查接收到的对象作为Invoke调用的参数,它是我之前创建的期望类型?或者唯一的方法是使用某种传递给JS的本地id并返回到本机代码,这样我就能在我的对象之间建立关联?
答案 0 :(得分:1)
浏览器通常会在将NPObject提供给另一个插件之前将其从一个插件中包装出来;我认为这是一个安全预防措施,它实际上意味着你不能做你想做的事情。但是,您可以做的是,您可以为每个NPObject提供某种形式的唯一ID,并在该对象上使用getID方法。然后你只需要一个内部的地图或类似的东西,你可以用它来获取你通过NPObject接口查询getID后所需的实际对象。