1

作成中のプラグインで呼び出されたメソッドを適切なプラグイン インスタンスに関連付ける際に問題が発生しています。http://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_pluginsのドキュメントは、これに関して真に役立つ十分な情報を提供していません。

一言で言えば、NPPpluginScriptableNPObject に等しい可変引数を指定した NPP_GetValue の呼び出しに応答して、プラグインが返すスクリプト可能なオブジェクトを理解しようとしています。プラグインのインスタンスごとに NPObject インスタンスが必要だと思いますが、NPClass の invoke() メソッドは、引数として与えられたスクリプト可能な NPObject からプラグイン インスタンス (NPP) をどのように見つけるのでしょうか? それを行うためにルックアップテーブルを実装できると思いますが、明らかに欠けているものがあると感じています。

NPP_New() の NPP の pdata メンバーに、C++ クラスのインスタンス (インスタンスはプラグインの機能を実装します) へのポインターを格納しています。

4

1 に答える 1

1

私は自分自身の質問に答えていると思います...

私が見つけた解決策 (そして、特にそれを行うためのより良い方法があると思われる場合は、その有効性に関するコメントをいただければ幸いです) は、公開する allocate() 関数で実装クラスへのポインターを持つ NPObject 派生構造を割り当てることでした。私のプラグインから Firefox へ。次に、その NPObject へのポインターを NPP_New() の NPP の pdata メンバーに格納します。

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;

}

于 2008-09-24T16:39:29.137 に答える