私は、C++ API を Lua コードに公開する「ホスト」アプリケーションを作成しようとしてきましたが、これまでのところかなり成功していますが、「変数」をメソッドにバインドしようとすると問題が発生しました。
「クラス」を lua にバインドするために私が開発したパターンには、各クラスに関数_new
と_gc
関数、および各クラスの staticluaL_Reg RegData[]
が含まれます。次に、目的の関数を RegData 配列に割り当て、ヘルパー メソッドを呼び出してそれらを lua にバインドします。以下は、私の方法を示すコードです。
int Host::_new(lua_State * ls)
{
Host ** udata = (Host **)lua_newuserdata(ls, sizeof(Host *);
*udata = new Host();
luaL_getmetatable(ls, "luaL_Host);
lua_setmetatable(ls, -2);
return 1;
}
int Host::_gc(lua_State * ls)
{
Host * host = *(Host **)luaL_checkudata(ls, 1, "luaL_Host");
delete host;
return 0;
}
const luaL_Reg Host::RegistrationData[] =
{
{ "new" , Host::_new },
{ "__gc" , Host::_gc },
{ 0 , 0 }
};
そして他の場所:
void LuaState::registerObject(const char * name, const luaL_Reg data[])
{
int len = strlen(name) + 6;
char * luaLname = new char[len];
snprintf(luaLname, len, "luaL_%s", name);
// create the metatable with the proper functions
luaL_newmetatable(_state, luaLname);
luaL_setfuncs(_state, data, 0);
// copy the metatable on the stack
lua_pushvalue(_state, -1);
// assign the index to the copy
lua_setfield(_state, -1, "__index");
// expose the table as the global "Host"
lua_setglobal(_state, name);
delete luaLname;
}
Lua コードでキーボードの状態も表示できるようにし、Lua コードで次のようにアクセスできるようにしたいとします。
host = Host.new()
pressed = host.Keyboard.getKeyPressed(1)
まったく同じパターンをキーボード クラスにコピーしてキーボード テーブルをセットアップするのは簡単ですが、そのキーボード テーブルをホスト テーブルに追加する良い方法が思いつかないようです。私のパターンを台無しにすることなくそうする簡単な方法はありますか? 私が使用すべきより良いパターンはありますか?
C-Lua API のさまざまな側面を作成する方法に関する多くのリソースを見つけましたが、その際に使用するパターン/ベスト プラクティスに関してはあまり見つかりませんでした。また、これに役立つLuaBindなどのライブラリがあることは知っていますが、自分で作成することを好みます(少なくとも初めて)。