Come posso associare un'istanza del plugin Mozilla tramite script al suo NObject?
Domanda
Sto riscontrando un problema nell'associare un metodo invocato in un plugin che sto scrivendo con l'istanza appropriata del plugin. La documentazione in http://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins non fornisce abbastanza informazioni per essere veramente utili al riguardo.
In poche parole, sto cercando di capire esattamente quale oggetto di script dovrebbe restituire il plugin in risposta a una chiamata a NPP_GetValue con l'argomento variabile uguale a NPPpluginScriptableNPObject. Immagino che ci dovrebbe essere un'istanza NPObject per ogni istanza del plug-in, ma come si suppone che il metodo invoke () in NPClass trovi l'istanza del plug-in (NPP) dal NPObject tramite script che viene fornito come argomento? Suppongo che potrei implementare una tabella di ricerca per farlo, ma ho la sensazione che manchi qualcosa di ovvio.
Sto memorizzando un puntatore a un'istanza di una classe C ++ (l'istanza implementa la funzionalità del plugin) nel membro pdata di NPP, in NPP_New ().
Soluzione
Suppongo di rispondere alla mia domanda ...
La soluzione che ho trovato (e apprezzerei ancora i commenti sulla sua validità, soprattutto se pensi che ci sia un modo migliore di farlo) era allocare una struttura derivata NPObject che ha un puntatore alla mia classe di implementazione in allocate () funzione che espongo a Firefox dal mio plugin. Quindi memorizzo un puntatore a quell'oggetto NPO nel membro pdata del NPP, in NPP_New ().
In invoke (), ho lanciato il puntatore NPObject che ottengo sui membri aggiuntivi della struttura derivata, in modo da poter ottenere un puntatore all'istanza della classe di implementazione.
Questo, per quanto ne so, è l'intento del progetto: gli oggetti NPObject sono istanze della NPClass a cui puntano, implementano metodi e proprietà attraverso i puntatori della funzione NPClass che si occupano di queste entità e di qualsiasi dato privato dovrebbe essere assegnato e deallocato dall'attuazione e il suo formato non è specificato.
Sarebbe simile a questo:
static NPClass refObject = {
NP_CLASS_STRUCT_VERSION,
My_Allocate,
My_Deallocate,
NULL,
My_HasMethod,
My_Invoke,
My_InvokeDefault,
My_HasProperty,
My_GetProperty,
NULL,
NULL,
};
class MyImplClass {
// Implementation goes here
};
struct MyNPObject : public NPObject {
MyImplClass *my_impl_instance;
};
// This is just a bit of memory management - Mozilla wants us to allocate our own memory:
NPObject *My_Allocate(NPP inst, NPClass *)
{
// We initialize the structure in NPP_New() below
return (NPObject *)malloc(sizeof(MyNPObject));
}
NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
char* argn[], char* argv[], NPSavedData* saved )
{
NPObject *scriptable_object = npnfuncs->createobject(instance, &refObject);
npnfuncs->retainobject(scriptable_object);
MyImplClass *new_player = new MyImplClass();
instance->pdata = scriptable_object;
((MyNPObject*)instance->pdata)->my_impl_instance = new_player;
return NPERR_NO_ERROR;
}