You call lua_resume on a thread returned by lua_newthread
, not lua_newstate
.
So in your code you would either have to change the first lua_resume
to 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);
or swap luaL_loadfile
for 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
I'm not relating to the efficiency of setting the global t
here.
Now to the main point of the question:
- First, each call to
lua_callk
,lua_pcallk
orlua_yieldk
needs to receive a continuation function as an argument. In your case it's 0. Actually,lua_yieldk
can take 0 as continuation function, but then control is passed back to Lua script, where the call to the C function occured. - Next, any call to those functions must be made within a coroutine thread, not the main thread.
- And lastly, you cannot yield across C call boundary. That is, when you call
lua_pcallk
and the chunk that pcallk is calling yields, the continuation function is executed. However, you cannot havelua_pcallk
call a Lua function that in turn calls a C function that yields (pause
in your example). That's forbidden.
An example of 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;
}
Lua code:
local pcallktest = ...
pcallktest()
Now this piece of code starts a new coroutine from file "Test.lua". The Lua code calls C function pcallktest
, which in turn calls lua_pcallk
on another Lua function, which just yields. When the yield occurs, execution jumps (longjmp) to the cont
function, which was provided as an argument to lua_pcallk
. When the cont
function returns, the coroutine execution ends and lua_resume
from the _tmain
returns.
An example of 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;
}
Lua code:
local yieldktest = ...
yieldktest()
This bit in turn executes coroutine that yields from within a C function (yieldktest
). When the coroutine is then resumed (the second lua_resume
), control is passed back to the continuation function cont
, which executes as a continuation of yieldktest
.
These examples do not deal with lua_getctx
and stack states, but merely demonstrate the mechanisms of those functions.