¿Cómo puedo asociar una instancia de complemento de Mozilla programable con su NObject?

StackOverflow https://stackoverflow.com/questions/125308

  •  02-07-2019
  •  | 
  •  

Pregunta

Me encuentro con un problema al asociar un método invocado en un complemento que estoy escribiendo con la instancia de complemento adecuada.La documentación en http://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins no proporciona suficiente información para ser realmente útil en esto.

En pocas palabras, estoy tratando de entender qué objeto programable se espera que devuelva el complemento en respuesta a una llamada a NPP_GetValue con el argumento variable igual a NPPpluginScriptableNPObject.Supongo que debería haber una instancia de NPObject para cada instancia del complemento, pero ¿cómo se supone que el método invoke() en NPClass encuentra la instancia del complemento (NPP) del NPObject programable que se proporciona como argumento?Supongo que podría implementar una tabla de búsqueda para hacer eso, pero tengo la sensación de que me falta algo obvio.

Estoy almacenando un puntero a una instancia de una clase C++ (la instancia implementa la funcionalidad del complemento) en el miembro pdata del NPP, en NPP_New().

¿Fue útil?

Solución

Supongo que estoy respondiendo mi propia pregunta...

La solución que encontré (y todavía agradecería comentarios sobre su validez, especialmente si cree que hay una mejor manera de hacerlo) fue asignar una estructura derivada de NPObject que tiene un puntero a mi clase de implementación en la función allocate() que expongo. a Firefox desde mi complemento.Luego almaceno un puntero a ese NPObject en el miembro pdata del NPP, en NPP_New().

En invoke(), lanzo el puntero NPObject que obtengo a los miembros adicionales de la estructura derivada, para poder obtener un puntero a la instancia de la clase de implementación.

Esa, hasta donde puedo decir, es la intención del diseño: los objetos NPObject son instancias de la NPClass a la que apuntan, implementan métodos y propiedades a través de los punteros de función NPClass que tratan con estas entidades, y se espera que cualquier dato privado ser asignado y desasignado por la implementación, y su formato no está especificado.

Se vería algo como esto:

 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;

}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top