Как я могу связать экземпляр плагина Mozilla со сценарием и его NObject? - PullRequest
1 голос
/ 24 сентября 2008

Я сталкиваюсь с проблемой, связывающей вызванный метод в плагине, который я пишу с соответствующим экземпляром плагина. Документация на http://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins не дает достаточно информации, чтобы быть действительно полезной в этом.

В двух словах, я пытаюсь понять, какой объект сценариев должен плагин возвращать в ответ на вызов NPP_GetValue с аргументом переменной, равным NPPpluginScriptableNPObject. Я предполагаю, что должен быть экземпляр NPObject для каждого экземпляра плагина, но как метод invoke () в NPClass должен находить экземпляр плагина (NPP) из сценариев NPObject, который задан в качестве аргумента? Я полагаю, что я мог бы реализовать справочную таблицу для этого, но у меня такое ощущение, что я чего-то не понимаю.

Я храню указатель на экземпляр класса C ++ (экземпляр реализует функциональность плагина) в члене pdata NPP, в NPP_New ().

1 Ответ

1 голос
/ 24 сентября 2008

Полагаю, я отвечаю на свой вопрос ...

Решение, которое я нашел (и я все равно буду благодарен за комментарии по поводу его валидности, особенно если вы считаете, что есть лучший способ сделать это), заключается в выделении производной структуры NPObject, которая имеет указатель на мой класс реализации в allocate () Функция, которую я открываю для Firefox из моего плагина. Затем я сохраняю указатель на этот объект NPO в члене pdata NPP в NPP_New ().

В invoke () я приведу указатель NPObject, который я получаю к дополнительным членам производной структуры, чтобы я мог получить указатель на экземпляр класса реализации.

Это, насколько я могу судить, является целью проекта - объекты NPObject являются экземплярами NPClass, на которые они указывают, они реализуют методы и свойства с помощью указателей на функции NPClass, которые имеют дело с этими объектами, и любыми частными данными. ожидается, что он будет выделен и освобожден реализацией, а его формат не указан.

Это будет выглядеть примерно так:

 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;

}

...