3

I'm trying to call a Lua function from C. The Lua function creates a table and then iterates through it. It works as expected when called from Lua, but not when I call it from a C program. Is there any reason why I can't do what I'm trying here?

test.lua:

function f()
    t = {["a"] = "aaa", ["b"] = "bbb", ["c"] = "ccc"}
    for z, v in t do
        print(t .. " " .. v)
    end
end

test.c:

#include <string.h>
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

int main(void)
{
    char read_buffer[1024];

    lua_State *L = lua_open();
    luaL_openlibs(L);
    if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0))
        fprintf(stderr, "Error loading test.lua");

    lua_getglobal(L, "f");

    if(lua_pcall(L, 0, 0, 0) != 0)
        fprintf(stderr, "error: %s\n", lua_tostring(L, -1));

    strncpy(read_buffer, lua_tostring(L, -1), sizeof(read_buffer));
    lua_pop(L, 1);
    printf("got from lua: %s\n", read_buffer);

    lua_close(L);

    return 0;
}

Thanks!

3
  • 1
    Don't you need to call load_dofile() instead of lua_loadfile()? Commented Dec 22, 2013 at 23:36
  • I believe luaL_dofile just calls lua_loadfile and lua_pcall: pgl.yoyo.org/luai/i/luaL_dofile Commented Dec 22, 2013 at 23:45
  • You usual do this using lua_next. They even has an example there. Commented Dec 23, 2013 at 3:35

1 Answer 1

2

I'm noticing a couple of issues above that's causing problems.

Over here:

function f()
  t = {["a"] = "aaa", ["b"] = "bbb", ["c"] = "ccc"}
  for z, v in t do
    print(t .. " " .. v)
  end
end

You can't use a lua table in the for in loop like that unless you make t callable in someway (eg. using __call for instance). More likely you're probably just trying to iterate through it, in which case you would use pairs:

  for z, v in pairs(t) do
  -- etc.

The other error is that you're trying to concat strings onto the table. Not sure what you were intending here. Perhaps you wanted to print the table address? You can use tostring for that.

The second issue I notice is in your C code:

if(lua_pcall(L, 0, 0, 0) != 0)

So you're not expecting f to return anything unless there's an error. But right after that you try to convert the top item into a string:

strncpy(read_buffer, lua_tostring(L, -1), sizeof(read_buffer));
lua_pop(L, 1);
printf("got from lua: %s\n", read_buffer);

which doesn't make a whole lot of sense -- there may not be anything on the stack at this point. This is clearly a logic error in your code. If this is suppose to be a part of the error handling you should enclose it in braces so it's properly scoped:

if(lua_pcall(L, 0, 0, 0) != 0)
{
    fprintf(stderr, "error: %s\n", lua_tostring(L, -1));
    strncpy(read_buffer, lua_tostring(L, -1), sizeof(read_buffer));
    lua_pop(L, 1);
    printf("got from lua: %s\n", read_buffer);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Oops, sorry - I meant to concat z and v, not t and v. With the C code, my original Lua function that I simplified for testing did return a string - I guess I forgot to edit the C accordingly. Didn't matter anyway since the Lua code would give me an error before that stuff. Anyway, using pairs to iterate through worked, thanks very much.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.