Lua coroutines and C++

Tonight I played around with coroutines in Lua. After some Googling I figured out how to create and communicate with a Lua-thread from C++. It turned out to be really simple.

The lua program “loop.lua”

counter = 0

function loop()
    while counter
    do
        print("Sending " .. counter);
        coroutine.yield(counter);
        counter = counter + 1;
    end
end

The C++ program

#include <stdio.h>

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

int main (void)
{
    lua_State *L = lua_open();
    luaL_openlibs(L);

    if (!luaL_loadfile(L, "loop.lua")) {
        lua_pcall(L, 0, 0, 0);
        lua_State *L2 = lua_newthread(L);
        lua_getglobal(L2, "loop");

        while (1) {
            puts("while top");
            int res = lua_resume(L2, 0);
            if (res != 0) {
                break;
            }

            if (lua_isnumber(L2, lua_gettop(L2)) == 1) {
                printf(
                    "Got %d\n",
                    lua_tonumber(L2, lua_gettop(L2))
                );
            }
        }
    }

    lua_close(L);
    return 0;
}
This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

4 Responses to Lua coroutines and C++

  1. Slone says:

    You are my hero. I’ve been searching for a way to manage coroutines from C for a half hour or so. This seems to be exactly what I need. Thanks!

  2. Slone says:

    Something else I thought I’d share that I found which would probably be useful for others reading this: you can kill an individual thread, but you don’t want to use lua_close to do it. You first get the refkey when you create the thread, then kill the reference to kill the thread.

    For example:

    // when creating the thread
    int result = lua_pcall(state, 0, 0, 0);
    thread->m_state = lua_newthread(state);
    thread->m_refkey = luaL_ref(state, LUA_REGISTRYINDEX);

    // when you want to kill it.
    lua_unref(m_state, m_refkey);

  3. Frank Neubecker says:

    Thanks so much! After a whole day of no progress this finally unblocked my road.

  4. Leith Ketchell says:

    This by itself is incomplete, but useful, as it shows that a coroutine, having been ‘resumed once’, requires no further args for resuming it again.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s