在我的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问题,一旦我在 setter/getter 中添加了
NPN_RetainObject()
(如您在上面看到的),一切就很好了。我在声明中没有找到Mozilla doc中需要它,也没有在Taxilian很棒的doc about NPAPI中得到它。
我不明白:当浏览器请求保留的属性时,为什么我必须再次保留它?
在调用
InvokeDefault()
时,是否应该保留该函数?但是,为什么呢?我已经说过要保留它。getProperty()
或InvokeDefault()
是否实际上在不告诉我的情况下做了NPN_ReleaseObject()
? 最佳答案
您始终必须使用NPAPI保留对象输出参数,这不特定于属性 getter 。
在您的特定情况下,对象可能仍然存在,但在一般情况下不会:
考虑将一个您不打算从插件中保留下来的对象返回给调用者。您必须将所有权转移给调用方,并且不能返回保留计数为0
的对象。
关于c++ - NPAPI:需要两次RetainObject()一个处理程序,否则SIGBUS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11824065/