2008-09-24 6 views
1

Je rencontre un problème d'association d'une méthode invoquée dans un plugin que j'écris avec l'instance de plugin appropriée. La documentation au http://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins ne donne pas assez d'informations pour être vraiment utile à ce sujet. En un mot, j'essaie de comprendre quel objet scriptable le plugin devrait retourner en réponse à un appel à NPP_GetValue avec l'argument variable égal à NPPpluginScriptableNPObject. Je devine qu'il devrait y avoir une instance de NPObject pour chaque instance du plugin, mais comment la méthode invoke() dans le NPClass est-elle supposée trouver l'instance de plugin (NPP) du NPObject scriptable donné comme argument? Je suppose que je pourrais implémenter une table de consultation pour faire cela, mais j'ai le sentiment qu'il y a quelque chose qui me manque.Comment associer une instance de plugin Mozilla scriptable à son NObject?

Je stocke un pointeur vers une instance d'une classe C++ (l'instance implémente la fonctionnalité du plugin) dans le membre pdata de la NPP, dans NPP_New().

Répondre

1

Je suppose que je réponds à ma question ...

La solution que je trouve (et je serais encore apprécier des commentaires sur sa validité, surtout si vous pensez qu'il ya une meilleure façon de le faire) était d'allouer une structure dérivée de NPObject qui a un pointeur vers ma classe d'implémentation dans la fonction allocate() que j'expose à Firefox depuis mon plugin. Je stocke alors un pointeur sur ce NPObject dans le membre pdata du NPP, dans NPP_New().

Dans invoke(), je lance le pointeur NPObject que j'attrape dans les membres supplémentaires de la structure dérivée, de sorte que je puisse obtenir un pointeur vers l'instance de la classe d'implémentation. Cela, autant que je sache, est l'intention de la conception - objets NPObject sont des instances de la NPClass vers laquelle ils pointent, ils implémentent des méthodes et des propriétés via les pointeurs de fonction NPClass qui traitent ces entités, et tout privé les données devraient être allouées et désaffectées par l'implémentation, et son format n'est pas spécifié.

Il ressemblerait à quelque chose comme ceci:

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; 

}

+1

Vous avez essentiellement frappé sur elle. Vous pouvez utiliser votre propre objet qui étend NPObject si vous voulez, pour le rendre un peu plus agréable et OO. Vous pouvez trouver un bon exemple dans le projet FireBreath, que je vous recommande également de consulter. voir http://code.google.com/p/firebreath/source/browse/src/NpapiPlugin/NPJavascriptObject.h – taxilian

Questions connexes