[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: How to use lua_yield/lua_resume in C correctly?
- From: Jerome Vuarand <jerome.vuarand@...>
- Date: Sun, 27 Jan 2013 23:51:02 +0000
2013/1/25 chuang <lichuang1982@gmail.com>:
> I try to use co-routines to simulate "pause" a script and wait until some
> processing is done before resuming,the C and Lua code is below, but it
> cannot work:
>
> main.c:
> #include <stdio.h>
> #include "lua.h"
> #include "lualib.h"
> #include "lauxlib.h"
>
> typedef int bool;
> #define true 1
> #define false 1
> bool running = true;
>
> int lua_finish(lua_State *L) {
> running = false;
> printf("lua_finish called\n");
> return 0;
> }
>
> int lua_sleep(lua_State *L) {
> printf("lua_sleep called\n");
> return lua_yield(L,0);
> }
>
> int main() {
> lua_State* L = lua_open();
> luaL_openlibs(L);
>
> lua_register(L, "sleep", lua_sleep);
> lua_register(L, "finish", lua_finish);
>
> lua_State* cL = lua_newthread(L);
> luaL_dofile(cL, "loop.lua");
>
> while (running) {
> int status;
> status = lua_resume(cL, 0);
> if (status == LUA_YIELD) {
> printf("loop yielding\n");
> } else {
> running=false; // you can't try to resume if it didn't yield
>
> if (status == LUA_ERRRUN && lua_isstring(cL, -1)) {
> printf("isstring: %s\n", lua_tostring(cL, -1));
> lua_pop(cL, -1);
> break;
> }
> }
> }
>
> lua_close(L);
> return 0;
> }
>
>
> loop.lua
> print("loop.lua")
>
> local i = 0
> while true do
> print("lua_loop iteration")
> sleep()
>
> i = i + 1
> if i == 4 then
> break
> end
> end
>
> finish()
>
> In Lua 5.1.4,when call lua_yield(),it thow "attempt to yield across
> metamethod/C-call boundary" error and return,so when call lua_resume in C it
> fails, how to fix it?
The problem is that your script is not run by a call to lua_resume.
That's because you run it with luaL_dofile. I think that you meant to
use luaL_loadfile instead, to push it on the coroutine stack before
calling lua_resume.
Tell us what you get when you replace luaL_dofile with luaL_loadfile.
And remember to always check the return value of luaL_loadfile and
luaL_dofile, to catch errors early.