私の 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()
が、ゲッターに を追加すると、上記のようにすべてがうまくいきました。
Mozilla docにも、 NPAPI に関するTaxilian の素晴らしいドキュメントにも必要であるという声明は見つかりませんでした。
よくわかりません: 保持したプロパティをブラウザが要求した場合、なぜ再度保持する必要があるのでしょうか?
InvokeDefault()
代わりに呼び出すときに関数を保持する必要がありますか? しかし、その後、なぜですか?? 保持したい旨はすでに述べた。
私に言わずにやりますか、getProperty()
それともInvokeDefault()
実際にNPN_ReleaseObject()
やりますか?