Как создать сопрограммы lua с помощью api lua c?

#c #api #lua

Вопрос:

Как создать сопрограммы lua с использованием api lua c и предоставить их lua?

Я пишу библиотеку на c для lua, и мне было интересно, как реализовать сопрограмму lua с использованием api lua c. Я в основном хочу реализовать что-то вроде следующего, где модуль написан на языке программирования си.

 module = require("mymodule")

coroutine.resume(module.coroutine_function, ...)
 

Комментарии:

1. В C вы создаете новый поток, lua_newthread а затем возобновляете любую функцию в нем. См . lcorolib.c в источниках Lua.

2. @lhf Я прошел через lcorolib.c , но у меня все еще есть некоторые проблемы. Моя функция сопрограммы выглядит так « int сопрограмма(lua_State* L) { lua_pushfstring(L, «Замечательно»); возвращает lua_yield(L, 1); }« И возобновление функции более одного раза не возвращает строку «wonderfull». Я хочу, чтобы сопрограмма продолжала выдавать строку «Чудесно». Что-то вроде этого « функция iter (), в то время как true выполняет сопрограмму. выход(«Чудесный») конец конца«

Ответ №1:

Следующий код на языке Си выдает строку «Wonderfull» 4 раза. И возвращает строку «End» перед завершением сопрограммы.

 static int kfunction(lua_State* L, int status, lua_KContext ctx)
{
    static int x = 0;
    
    if (x < 3)
    {
        x  ;
        lua_pushfstring(L, "Wonderfull");
        return lua_yieldk(L, 1, 0, kfunction);
    }
    lua_pushfstring(L, "End");
    return 1;
}

static int iter(lua_State* L)
{
    lua_pushfstring(L, "Wonderfull");
    return lua_yieldk(L, 1, 0, kfunction);
}


int luaopen_module(lua_State* L) {
    // initial function which is called when require("module") is run

    lua_State* n = lua_newthread(L);
    lua_setglobal(L, "coroutine_function");

    lua_pushcfunction(n, iter);

    return 0;
}
 

Использование модуля C в Lua:

 require("module")

print(coroutine.resume(coroutine_function))  -- true  Wonderfull
print(coroutine.resume(coroutine_function))  -- true  Wonderfull
print(coroutine.resume(coroutine_function))  -- true  Wonderfull
print(coroutine.resume(coroutine_function))  -- true  Wonderfull
print(coroutine.resume(coroutine_function))  -- true  End
print(coroutine.resume(coroutine_function))  -- false cannot resume dead coroutine
 

int iter(lua_State* L) вызывается, когда coroutine.resume вызывается в первый раз. Последующие звонки должны быть int kfunction(lua_State* L, int status, lua_KContext ctx) .

4-й аргумент to lua_yieldk может быть использован в качестве следующей функции, которую Lua должен вызвать, чтобы получить следующий выход или возвращаемое значение.

Документация: Обработка урожайности в C