我有以下代码,试图理解 C-Api 、 lua_resume 、延续和不同的情况,只是为了文档提到的过期。我目前在 ubuntu 桌面上使用 lua 5.4。 我有以下代码:
// Attempt to yield C-Function, into protected mode. - Continuation Function -
static int finishpcall (lua_State *L, int status, intptr_t ctx) {
(void)ctx; // unused parameter
status = (status != LUA_OK && status != LUA_YIELD);
lua_pushboolean(L, (status == 0)); // status
lua_insert(L, 1); // status is first result
printf("%s, %d\n", "From lua", lua_gettop(L)); // it is lua's stack frame = 1
lua_getglobal(L, "co");
lua_resume(lua_tothread(L, 2), NULL, 0, 0);
lua_resume(lua_tothread(L, lua_gettop(L)), NULL, 0, 0);
return lua_gettop(L); // return status + all results
}
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, finishpcall);
return finishpcall(L, status, 0);
}
int main(void) {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
// Register luaB_pcall as a Lua function
lua_register(L, "pcall", luaB_pcall);
const char *str = "function test() \
local co = coroutine.create(function() print('me') \
coroutine.yield() \
print('me me') \
end) \
return co \
end \
pcall(test)";
int res = luaL_dostring(L, str);
if (res != LUA_OK) {
printf("Error running Lua code: %s\n", lua_tostring(L, -1));
lua_close(L);
return 1;
}
printf("%s, %d\n", "From C-Function", lua_gettop(L)); //it is C's stack frame = 0
lua_close(L);
return 0;
}
任何人都可以告诉我为什么我在 finishpcall() 中的 lua_resume 上遇到分段错误,尽管首先我得到 From lua, 2 我作为结果。
仔细阅读手册,你会发现
lua_resume
最后一个参数的类型是int*
,它是一个输出参数。
int lua_resume (lua_State *L, lua_State *from, int nargs, int *nresults);
虽然在你的例子中,它是0,但一般来说,你需要处理它们。
lua_State* co = lua_tothread(L, 2);
int nresults;
status = lua_resume(co, NULL, 0, &nresults);
lua_pop(co, nresults); //handle the results by removing them
您也应该在第二个
co
调用中使用上面的 lua_resume
变量,因为您将全局 co 放在堆栈顶部,并且忘记弹出它们(协程也应该弹出)。