lua_resume 有分段错误

问题描述 投票:0回答:1

我有以下代码,试图理解 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 continuations c-api
1个回答
0
投票
  1. 仔细阅读手册,你会发现

    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
    
  2. 您也应该在第二个

    co
    调用中使用上面的
    lua_resume
    变量,因为您将全局 co 放在堆栈顶部,并且忘记弹出它们(协程也应该弹出)。

© www.soinside.com 2019 - 2024. All rights reserved.