代码之家  ›  专栏  ›  技术社区  ›  Ori Pessach

如何将可编写脚本的Mozilla插件实例与其对象关联?

  •  1
  • Ori Pessach  · 技术社区  · 17 年前

    我在将我正在编写的插件中调用的方法与相应的插件实例关联时遇到了一个问题。文件位于 http://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins 没有提供足够的信息来真正有用。

    简言之,我试图理解插件应该返回哪个可脚本对象,以响应对npp_GetValue的调用,变量参数等于npppluginScriptablenObject。我猜想插件的每个实例都应该有一个NPObject实例,但是NPClass中的invoke()方法应该如何从它作为参数提供的可脚本NPObject中找到插件实例(NPP)?我想我可以实现一个查找表来实现这一点,但是我感觉有一些明显的我遗漏了。

    我正在存储一个指针,指向一个C++类的实例(实例实现了插件的功能),在NPP的NPDJEY()中的PdATA成员中。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Ori Pessach    17 年前

    我想我是在回答我自己的问题…

    我发现的解决方案(我仍然很感激对其有效性的评论,特别是如果你认为有更好的方法可以做到这一点)是分配一个NPObject派生的结构,它在我从插件中向firefox公开的allocate()函数中有一个指向我的实现类的指针。然后,我在npp的pdata成员npp_new()中存储一个指向该np对象的指针。

    在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;
    

    }