lua c api - 协程相关

协程相关api的使用:

lua_tothread, lua_resume, lua_xmove

 

static int TestCo(lua_State* L) {
    //默栈上的元素: { coThread, param1, param2... }

    lua_State *co = lua_tothread(L, 1);
    //协程栈上的元素: { coFun }
    int topNum = lua_gettop(L);
    int argsNum = topNum - 1;

    // 将额外参数复制到协程栈
    for (int i = 2; i <= topNum; ++i) {
        lua_pushvalue(L, i);
        lua_xmove(L, co, 1); //从栈L弹出1个元素, 压入co栈
    }
    //默认栈上的元素: { coThread, param1, param2 }
    //协程栈上的元素: { coFun, param1, param2 }

    int code = lua_resume(co, argsNum); //执行完弹出argsNum+1个元素
    printf("TestCo: code: %d\n", code);
    if (0 == code || LUA_YIELD == code) { //未发生错误, 栈顶压入yield的参数或coFun的返回值
        //默认栈上的元素: { coThread, param1, param2 }
        //协程栈上的元素: { retVal1, retVal2 }

        int nRet = lua_gettop(co);
        lua_xmove(co, L, nRet); // 将结果移回主栈
        //默认栈上的元素: { coThread, param1, param2, retVal1, retVal2 }
        //协程栈上的元素: { }

        return nRet; //栈顶弹出n个元素, 作为lua层拿到的返回值
    }
    else { //发生错误, 栈顶压入错误描述
        //默认栈上的元素: { coThread, param1, param2 }
        //协程栈上的元素: { param1, param2, print, "coFun begin:", param1, param2, errDesc, errDesc, errDesc }
        lua_xmove(co, L, 1); // 将错误描述移回主栈
        lua_error(L); //报异常, 使用栈顶文本作为错误描述, 不会再往下执行

        return 0;
    }
}

lua c库入口

static const struct luaL_reg mylib_funcs[] = {
    {"TestCo", TestCo},
    {0, 0}
};

LUALIB_API int luaopen_mylib(lua_State *L) {
    // 栈上的元素: { "mylib" }

    luaL_openlib(L, "mylib", mylib_funcs, 0); //新建表mylib, 压入栈顶, 将表保存在: 栈[LUA_GLOBALSINDEX]["mylib"] = mylib, 函数注册在mylib下
    // 栈上的元素: { "mylib", mylib表 }

    return 1; //栈顶弹出1个元素, 作为lua层拿到的返回值
}

 

lua测试代码1

local function Test8()
    local mylib = require("mylib")
    
    local co = coroutine.create(function(str, num)
        print("coFun begin:", str, num)
        print("yield 1:", coroutine.yield("step2", 2))
        print("coFun end:")
        return "step4", 4
    end)

    mylib.TestCo(co, "step1", 1)
    print(coroutine.status(co))
    
    mylib.TestCo(co, "step3", 3)
    print(coroutine.status(co))
end

Test8()

运行结果

 

 

lua测试代码2:测试报错的情况

local function Test9()
    local mylib = require("mylib")
    local co = coroutine.create(function(str, num)
        print("coFun begin:", str, num)
        local a = 1 + nil
        
        print("coFun end")
    end)

    mylib.TestCo(co, "step1", 1)
    print(coroutine.status(co))
end

Test9()

运行结果

 

posted @ 2025-07-11 23:22  yanghui01  阅读(12)  评论(0)    收藏  举报