inaka
nk8****@tcat*****
2003年 5月 11日 (日) 11:05:32 JST
はじめまして、D.N.A.さん。 僕もどうにかしてプラグインの基本となるクラスや エクスポート関数を使い回しできるようにと思い、 試行錯誤した結果、次のような感じになりました。 ・プラグインの基本となるクラスを作る。 →プラグイン仕様書のプラグインが最低限実装すべき関数を抽象的に持つクラス を作る ・エクスポート関数が処理の対象とするプラグインを入れる静的なコンテナ(以 下 StaticPluginContainerとします)を作る。 ここで言うコンテナは、本当にただの箱みたいな感じで、 エクスポート関数はStaticPluginContainerに入れられたプラグインクラスを処 理対象にします。 ・DllMainでプラグインのインスタンスを作り、StaticPluginContainer に入れる 流れはこんな感じです。 それぞれのクラスはこんな感じに実装しました。 // 必要最低限の関数を実装した抽象クラス class AbstractNsmPlugin { public: virtual int Initialize(InitInfo* initinfo) = 0; virtual int Terminate() = 0; virtual int GetPluginInfo(int infono, LPTSTR buf, int size) = 0; }; // エクスポート関数が処理するプラグインを入れる箱 class StaticPluginContainer { public: static void attach(AbstractNsmPlugin* plugin) { plugin_ = plugin; } static void detach() { attach(0); } static AbstractNsmPlugin* get() { return plugin_; } private: static AbstractNsmPlugin* plugin_; }; AbstractNsmPlugin* AbstractNsmPlugin::plugin_ = 0; // エクスポート関数の定義 EXPORT int Initialize(InitInfo* initinfo) { StaticPluginContainer::get()->Initialize(initinfo); } EXPORT int Terminate() { StaticPluginContainer::get()->Terminate(); } EXPORT int GetPluginInfo(int infono, LPTSTR buf, int size) { StaticPluginContainer::get()->GetPluginInfo(infono, buf, size); } // プラグインの実装 class NsmPlugin : public AbstractNsmPlugin { public: virtual int Initialize(InitInfo* initinfo){ /* 処理 */ } virtual int Terminate(){ /* 処理 */ } virtual int GetPluginInfo(int infono, LPTSTR buf, int size){ /* 処理 */ } }; // メイン関数 int DllMain(...) { static NsmPlugin* plugin_ptr = 0; switch (fdwReason) { case DLL_PROCESS_ATTACH: plugin_ptr = new NsmPlugin(); NsmPluginContainer::attach(plugin_ptr); break; case DLL_PROCESS_DETACH: NsmPluginContainer::detach(); delete plugin_ptr; break; } } 長くなりましたが以上です。 D.N.Aさんのおっしゃられた、 > なにか、1つグローバル変数を用意しておいて、そのなかに派生クラスのポインター > を入れ、エクスポート関数でそれを使用するようにすればうまくいくかもしれません > が…。 とまさに同じで、1つのグローバル変数がStaticPluginContainerとなってます。 サービスやイベントもこの調子で実装していくとなると、 ちょっと大変かもです...(^^; inaka