1

在我的 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()

4

1 回答 1

2

您始终必须使用 NPAPI 保留对象输出参数,这并非特定于属性获取器。

在您的特定情况下,该对象可能仍然保持活动状态,但在一般情况下不会:
考虑将一个对象返回给您不打算通过插件保持活动状态的调用者。您必须将所有权转移给调用者,并且不能返回保留计数为0.

于 2012-08-06T09:28:08.487 回答