在我的 NPAPI 插件中,一些对象具有可读可写的“onEvent”属性,并在某些事件上调用。
我的 Javascript 代码中的内容如下所示:
myObject.onEvent = function( event ) {
console.log("Event: " + event );
}
// if I put this next line, the next call to the 'onEvent' handler will SIGBUS
// when there's no RetainObject() in the getter.
console.log("Event handler : " + myObject.onEvent);
在插件的 C++ 端,我有这样的代码:
bool MyPluginObject::getOnEvent(NPIdentifier id, NPVariant *result)
{
if( _onEvent )
{
OBJECT_TO_NPVARIANT( _onEvent, *result);
NPN_RetainObject( _onEvent ); // needed ???? why??
}
else
VOID_TO_NPVARIANT(*result);
return true;
}
bool MyPluginObject::setOnEvent( NPIdentifier id, const NPVariant *value )
{
if ( value && NPVARIANT_IS_OBJECT( *value ) )
{
if( _onEvent != NULL )
{
// release any previous function retained
NPN_ReleaseObject( _onEvent );
}
_onEvent = NPVARIANT_TO_OBJECT( *value );
NPN_RetainObject( _onEvent ); // normal retain
return true;
}
return false;
}
void MyPluginObject::onEvent(void)
{
NPVariant event = [...];
if ( _onEvent!= NULL )
{
NPVariant retVal;
bool success = NPN_InvokeDefault( _Npp, _onEvent, &event, 1, &retVal );
if( success )
{
NPN_ReleaseVariantValue(&retVal);
}
}
}
奇怪的是,我一直在为一个 SIGBUS 问题苦苦挣扎,一旦我NPN_RetainObject()
在 getter 中添加了,正如你在上面看到的,一切都很好。
我没有在Mozilla 文档中找到需要它的声明,在 Taxilian关于 NPAPI的很棒的文档中也没有发现。
我不明白:当浏览器请求我保留的属性时,为什么我必须第二次保留它?
我应该在调用InvokeDefault()
它时保留该功能吗?但是,为什么?我已经说过我想保留它。
是在不告诉我的情况下做getProperty()
或InvokeDefault()
实际上做的吗?NPN_ReleaseObject()