lua_newthread
ではなく、によって返されたスレッドで lua_resume を呼び出しますlua_newstate
。
lua_resume
したがって、コードでは、最初のものを次のように変更する必要がありますlua_(p)call
。
if (luaL_loadfile(L, "test.lua"))
error(L, "cannot run script %s\n", lua_tostring(L,-1));
lua_pcall(L, 0, 0, 0);
または交換luaL_loadfile
:luaL_dofile
if (luaL_dofile(L, "test.lua"))
error(L, "cannot run script %s\n", lua_tostring(L,-1));
//lua_resume(L, NULL, 0); Not necessary anymore
ここでグローバルを設定する効率とは関係ありませんt
。
さて、質問の要点:
- まず、 または を呼び出すたびに
lua_callk
、lua_pcallk
継続lua_yieldk
関数を引数として受け取る必要があります。あなたの場合は 0 です。実際にlua_yieldk
は、継続関数として 0 を使用できますが、制御は、C 関数の呼び出しが行われた Lua スクリプトに戻されます。
- 次に、これらの関数への呼び出しは、メイン スレッドではなく、コルーチン スレッド内で行う必要があります。
- そして最後に、C 呼び出しの境界を越えて譲歩することはできません。つまり、呼び出し
lua_pcallk
て、pcallk が呼び出しているチャンクが生成されると、継続関数が実行されます。lua_pcallk
ただし、 (この例では) を生成する C 関数を呼び出す Lua 関数を呼び出すことはできませんpause
。それは禁じられています。
例lua_pcallk
:
int cont(lua_State *L)
{
getchar();
return 0;
}
int pcallktest(lua_State *L)
{
luaL_loadstring(L, "yield()");
int test = lua_pcallk(L, 0, 0, 0, 0, cont);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_State *T = lua_newthread(L);
luaL_loadfile(T, "Test.lua");
lua_pushcfunction(T, pcallktest);
lua_resume(T, NULL, 1);
return 0;
}
ルアコード:
local pcallktest = ...
pcallktest()
このコードは、ファイル「Test.lua」から新しいコルーチンを開始します。Lua コードは C functionpcallktest
を呼び出し、それはlua_pcallk
別の Lua 関数を呼び出します。cont
yield が発生すると、実行は への引数として提供された関数にジャンプ (longjmp) しlua_pcallk
ます。関数がcont
戻ると、コルーチンの実行が終了lua_resume
し、_tmain
戻ります。
例lua_yieldk
:
int cont(lua_State *L)
{
getchar();
return 0;
}
int yieldktest(lua_State *L)
{
return lua_yieldk(L, 0, 0, cont);
}
int _tmain(int argc, _TCHAR* argv[])
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_State *T = lua_newthread(L);
luaL_loadfile(T, "Test.lua");
lua_pushcfunction(T, yieldktest);
lua_resume(T, NULL, 1);
lua_resume(T, NULL, 0);
return 0;
}
ルアコード:
local yieldktest = ...
yieldktest()
このビットは、C 関数内から発生するコルーチンを実行します ( yieldktest
)。その後、コルーチンが再開されると (2 回目lua_resume
)、制御が継続関数に戻され、継続cont
として実行されyieldktest
ます。
これらの例はlua_getctx
、状態を処理したりスタックしたりするのではなく、それらの機能のメカニズムを示すだけです。