C++ プログラムにユーザーデータとして Lua に渡すオブジェクトがあり、このユーザーデータのメタテーブルをオーバーライドして、(__newindex および __index を介して) オブジェクトのインデックスとの間で代入を行うと、代入を変換する C が呼び出されるようにします。 C++ オブジェクトに影響を与えるか、C++ 要素を Lua 値 (別のユーザーデータまたは bool、number、string などの基本型) に変換します。ユーザーデータは、C++ プログラムから呼び出されるイベントのような Lua 関数に引数として渡されます。
luaL_newmetatable(L, "object");
lua_pushstring(L, "__index");
lua_pushvalue(L, -2); /* pushes the metatable */
lua_settable(L, -3); /* metatable.__index = metatable */
luaL_openlib(L, NULL, vallib_m, 0);
luaL_openlib(L, "internal", vallib_f, 0);
lua_pushstring(L, "__index");
lua_pushstring(L, "get");
lua_gettable(L, 2); /* get val.get */
lua_settable(L, 1); /* metatable.__index = val.get */
lua_pushstring(L, "__newindex");
lua_pushstring(L, "set");
lua_gettable(L, 2); /* get array.set */
lua_settable(L, 1); /* metatable.__newindex = val.set */
ただし、これにより、実際の変数自体を割り当てることはできず、変数のインデックスのみを割り当てることができます。代入演算子を直接オーバーライドするためのメタイベントがないため、回避策を探しています。
言い換えれば、私はこれを行うことができます:lua_userdata_object_passed_as_arg_to_event["is_it_true"]=true
そして、Lua ブール値を内部 C++ オブジェクトに割り当てますが、これを行うと:
lua_userdata_object_passed_as_arg_to_event = new_object()
Lua 変数が参照するものは変更されますが、私が理解しているように、コア オブジェクトには何もしません。それ。
私が検討した回避策の 1 つは、開発者がlua_userdata_object_passed_as_arg_to_event["__self"] = new_object()
オブジェクト自体を変更したい場合に行う必要のあるハックですが、これは望ましくありません。
そのため、グローバル変数を使用して代入演算子をオーバーライドし、グローバルなメタテーブル代入演算子をオーバーライドする独自の解決策をいくつか見つけましたが、誰かがこの解決策を説明するのを手伝ってくれるかどうかを探しています。http://lua-users.org/lists/lua-l/2012-01/msg00413.htmlおよびhttps://www.lua.org/pil/14.2.htmlを参照してください。特に、変数はグローバルではなく関数の引数なので、C API を介してグローバルに変換し、グローバル ユーザーデータに対して割り当てが行われた場合にアクションを実行するカスタム C 関数によって割り当てがキャプチャされるようにするにはどうすればよいでしょうか?
ちなみに、私のユーザーデータはオブジェクトへのポインターであり、それが問題になる場合は、大きなオブジェクトの複製を回避します。