後で非同期で呼び出すためにLuaクロージャを格納する方法が必要です。lua - Cでストアを閉じ、Cでasyncを呼び出す
- 第二のアイデアは、私はそれをプッシュし、後でそれを呼び出すことができ、メタテーブルにクロージャを保存することでしたが、
- 直接私の最初のアイデアだった
lua_tocfunction
が、閉鎖がcfunctionではなく、Cから呼び出すことができませんそれは私がコピー閉鎖できないようです。 ()。
だから私はあなたの助けが必要です。クロージャーはどのように保存できますか?
私はどこかからその部分をコピーしたので、なぜ私のルアー・コーラーに__index
フィールドがあるのか完全に理解していないことを認めます。
ところで:onrender
のないプログラムは期待どおりに動作しました。私はqt guiを使用していて、の後には qtのメインループの後にルア状態が閉じられているので、作成されたウィンドウはスクリプトの後に__gc
によって削除されません。
bootstrap.lua
local w = w_render() -- create window object
w:show()
w:onrender(function()
print('render')
end)
w_lua.cppあなたの問題は、間違ったインデックスを使用してから派生し、間違った上でフィールドを設定/取得しようとしているように見えます
// chlua_* are helper macros/templates/methods
// 1: self
// 2: render closure
int w_render_onrender(lua_State *L) {
auto *self = chlua_this<GLWindow *>(L, 1, w_render_table);
lua_pushvalue(L, 2); // copy closure to top
lua_setfield(L, 2, "onrender_cb"); // save closure in metatable
// !!! ERROR: attempt to index a function value
self->onrender([L](){
lua_getfield(L, 2, "onrender_cb");
qDebug() << "onrender";
lua_call(L, 0, 0);
});
return 0;
}
// Creates the object
int w_render(lua_State *L) {
auto *&self = chlua_newuserdata<GLWindow *>(L);
self = new GLWindow;
if (luaL_newmetatable(L, w_render_table)) {
luaL_setfuncs(L, w_render_methods, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
lua_setmetatable(L, -2);
return 1;
}
あなたはインデックスが右 'w_render_onrender'であるよろしいです:私は仮定していますが、
self->onrender
が実際に実行したときにスタック上にあると何が起こるかを気にする必要はありません。この方法では、非同期のですか?私はあなたの 'GLWindow * 'を表す自己udataが最初のものであると仮定しています。この場合、 'lua_setfield(L、-3、" onrender_cb ");や' lua_setfield(L、1、 "onrender_cb"); ' – greatwolf私はあなたがする必要があると思います 'lua_getmetatable(L、1);実際にフィールドを設定しようとする前に、lua_insert(L、-2);私はpushvalueが本当にここで本当に必要であるか分からない。あなたが 'closure 'を取り戻す' lua_getfield'を行っているので、あなたの 'onrender'ラムダではこれは使われません。 – greatwolf
@greatwolf私はあなたの2つのソリューションを試しました:-3または1は私に 'ユーザデータ値をインデックス化しようとしました 'を与え、2番目の解決策は'私はユーザデータ値をインデックス化しようとします。私が気づいたことの1つは、get/setfieldは[doc](https://www.lua.org/manual/5.2/manual.html#lua_setfield)から '1'で呼び出されるべきです、ということです。インデックスはテーブルがスタックに格納されている場所で、ラムダの実装がどのように確実で、テーブルが存在し、その間にスタックが変更されたのか不思議です。 – Aitch