Вызвать Lua функцию из таблицы Lua через lua C Api

254
14 марта 2018, 06:41

У меня есть следующий код на Lua:

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

Я пытаюсь из плюсов достучаться до этой функции (демонстрационный пример, но структура та же) :

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

Однако у меня не получается это сделать, всегда получаю нуль в качестве результата. Помогите пожалуйста разобраться в чем тут может быть загвоздка.

Answer 1

У вас в вопросе, код на Lua нерабочий. Должно быть вот так:

-- объявление функции
main_ds.teg.Size = function(self) 
    return 5 
end
-- вызов
print(main_ds.teg:Size()) -- что на самом деле: main_ds.teg.Size(teg)

После этого исправления ваш Си-код должен начать работать и в результате на стеке будет "5".

Если хотите использовать self внутри функции на Lua (обычно это надо), то перед вызовом функции на стек нужно положить таблицу teg:

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);

Как выяснилось из комментариев, код на Lua написан топикстартером от балды и на самом деле таблицы создаются в Си. И, очевидно, создаются они неправильно, поэтому вот вдогонку пример, как можно создать глобальную таблицу, внутри неё вложенную таблицу, внутри которой есть функция:

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");

Вызываемая функция:

int size_func(lua_State *L)
{
    lua_pushnumber(L, 5);
    return 1;
}
READ ALSO
Рандом ASCII C++

Рандом ASCII C++

Можно ли как то рандомить символы из ASCII C++? Если да то как? А то массивы символов не хочется вводить

231
Быстрое считывание с++

Быстрое считывание с++

Здравствуйте, нужна помощь с написанием быстрого считывания из файла с помощью getchar_unlock()В файле есть две строки не обязательно одинакового...

304
Передача параметра в поток

Передача параметра в поток

Есть классВ поток есть возможность передать параметр

258
Понять лексер на конечном автомате

Понять лексер на конечном автомате

Привет!Хочу понять как сделать лекссер на C++Анализировал лексеры на Питон

202