C++ NPAPI:需要将处理程序保留两次,否则为SIGBUS

C++ NPAPI:需要将处理程序保留两次,否则为SIGBUS,c++,npapi,browser-plugin,sigbus,C++,Npapi,Browser Plugin,Sigbus,在我的NPAPI插件中,一些对象具有可读写的“OneEvent”属性,在某些事件中调用该属性 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 Reta

在我的NPAPI插件中,一些对象具有可读写的“OneEvent”属性,在某些事件中调用该属性

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问题有一段时间了,当我在getter中添加了
NPN\u RetainObject()
,正如您在上面看到的,一切都很顺利

我在声明中没有发现,在《泰克斯林的真棒》中,它也不是必需的

我不明白:当浏览器请求我保留的属性时,为什么我必须再次保留它

我是否应该在调用
InvokeDefault()
时保留该函数?但是,为什么呢??我已经说过我想保留它


getProperty()
InvokeDefault()
是否在没有告诉我的情况下实际执行了一个
NPN\u ReleaseObject()

您始终必须使用NPAPI保留对象输出参数,这不是特定于属性getter的

在您的特定情况下,对象可能仍然处于活动状态,但在一般情况下不会:

考虑将一个对象返回给调用方,而不是计划从插件中保持活力。您必须将所有权转移给调用者,并且您不能返回保留计数为
0

的对象,因此如果我完全理解您的意思:这是因为当浏览器请求“OneEvent”属性,而我将其交给他时,我会默默地将所有权交给他?有关于这件事的医生吗?我明白你的意思,但是两次保留对象(一次在set()上,一次在get()上)似乎很奇怪。是的,浏览器希望对象已经被保留。如前所述,在这种特定情况下可能看起来很奇怪,但您需要了解ref计数API的一般用法。所有参数都需要被被调用方保留,如果他想保持它们(它们在调用过程中必须生存),所有的参数都必须被被调用方保留:考虑将一个对象传递给调用方而不引用的情况。除了像这样的旁注。当我有时间的时候,我会在上面加上一节。