私は現在、Lua スクリプト インターフェイスを提供する C++ でプラグイン ベースのシステムを開発しており、そのために luabind を使用することにしました。Lua 5 と luabind 0.9 を使用しています。両方とも静的にリンクされ、MSVC++ 8 でコンパイルされています。関数が派生クラスで定義されているが、その親クラスでは定義されていない場合、関数を luabind にバインドする際に問題が発生しています。
より具体的には、すべてのプラグイン クラスが継承する「IPlugin」という抽象基本クラスがあります。プラグイン マネージャーが初期化されると、そのクラスとその関数が次のように登録されます。
luabind::open(L);
luabind::module(L) [
luabind::class_<IPlugin>("IPlugin")
.def("start", &IPlugin::start)
];
どの効果的なプラグイン クラスが使用可能かは実行時にしか分からないため、プラグインのロードを一種の回り道で解決する必要がありました。プラグイン マネージャーは、ファクトリ関数を Lua に公開します。この関数は、プラグイン クラスの名前と目的のオブジェクト名を受け取ります。次に、ファクトリはオブジェクトを作成し、プラグインのクラスを「IPlugin」基本クラスから継承するものとして登録し、次のように、Lua の状態を持つグローバルとして自身を登録する作成されたオブジェクトで関数をすぐに呼び出します。
void PluginExample::registerLuaObject(lua_State *L, string a_name)
{
luabind::globals(L)[a_name] = (PluginExample*)this;
}
Luaがオブジェクトの最も派生したクラスを決定する際に問題があったため、最初にこれを行いました。プラグインマネージャーから登録した場合、特定のサブタイプではなく「IPlugin」のサブタイプとしてのみ知られています。これが必要かどうかはもうわかりませんが、機能し、作成されたオブジェクトはその後「a_name」の下で Lua からアクセスできます。
しかし、私が抱えている問題は、親クラスでまったく宣言されていない派生クラスで定義された関数を使用できないことです。上記の「start」など、基本クラスで定義された仮想関数は正常に動作し、新しいオブジェクトで Lua からそれらを呼び出すと、「PluginExample」クラスからそれぞれ再定義されたコードが実行されます。しかし、「PluginExample」に新しい関数を追加すると、たとえば、引数を取らずに void を返す関数を追加し、次のように登録します。
luabind::module(L) [
luabind::class_<PluginExample, IPlugin>("PluginExample")
.def(luabind::constructor<PluginManager&>())
.def("func", &PluginExample::func)
];
新しいオブジェクトで「func」を呼び出すと、次の Lua ランタイム エラーが発生します。
一致するオーバーロードが見つかりません。候補: void func(プラグイン例&)
「:」構文を正しく使用しているため、「self」引数は必要ありません。突然、Lua がオブジェクトの派生型を判断できなくなったようです。おそらく私のシステム アーキテクチャで必要とされる 2 段階のバインドに関係しているのでしょうが、どこが間違っているのかわかりません。助けていただければ幸いです=)