Call a Lua function from a Lua table via the lua C Api

I have the following code in Lua:

main_ds = {};
main_ds.teg={};
main_ds.teg:Size = function () return 5; end;

I'm trying to get through to this function from the pros (demo example, but the structure is the same):

lua_settop(L,0);
lua_getglobal(L,"main_ds");
lua_getfield(L,-1,"teg");
lua_getfield(L,-1,"Size");

lua_remove(L,-3);
lua_remove(L,-2);
lua_call(L,0,1); // должен вернуть 5

However, I can't do it, I always get zero as the result. Please help me figure out what the hitch might be.

 1
Author: AndreyKrivcov, 2018-03-11

1 answers

In your question, the code on Lua is non-working. It should be like this:

-- объявление функции
main_ds.teg.Size = function(self) 
    return 5 
end

-- вызов
print(main_ds.teg:Size()) -- что на самом деле: main_ds.teg.Size(teg)

After this fix, your C code should start working and the result on the stack will be "5".

If you want to use self inside a Lua function (this is usually necessary), then you need to put the {[5] table on the stack before calling the function]}:

lua_State* L = luaL_newstate();
luaL_openlibs(L);

int err = luaL_dofile(L, "test.lua");
if (err) {
   printf("Cannot dofile: %s", lua_tostring(L, -1));
   lua_pop(L, 1);
   return 1;
}    

lua_getglobal(L, "main_ds");        
lua_getfield(L, -1, "teg");
lua_getfield(L, -1, "Size");

lua_pushvalue(L, -2); // параметр "self" = таблица "teg"

if(lua_pcall(L, 1, 1, 0) != 0) {
    printf("Func call failed: %s", lua_tostring(L, -1));
    lua_pop(L, 1);
    return 1;
}    

int ret = lua_tonumber(L, -1);
lua_pop(L, 3);

printf("ret = %d\n", ret);

As it turned out from the comments, the code in Lua is written by topikstarter from balda and in fact the tables are created in C. And, obviously, they are created wrong, so here's an example of how you can create a global table, inside it a nested table, inside which there is a function:

lua_createtable(L,0,0); // main_ds
lua_createtable(L,0,0); // teg
lua_pushcfunction(L, size_func);
lua_setfield(L, -2, "Size"); // set teg.Size
lua_setfield(L, -2, "teg"); // set main_ds.teg
lua_setglobal(L, "main_ds");

Called function:

int size_func(lua_State *L)
{
    lua_pushnumber(L, 5);
    return 1;
}
 1
Author: zed, 2018-03-13 07:43:28