Вызов функции lua, которая возвращает таблицу

Я знаю основы взаимодействия с lua и C, и в настоящее время я пытаюсь выполнить следующую строку lua в c ++

Func1():Func2().Table1.value1

Я пытаюсь получить значение «value2» и использовать его в моей C-программе. Ниже приведен код, который я написал, чтобы попытаться получить это значение в C.

int GetNumber()
{
int retn = 0;
g_clientlua.lua_getfield(LUA_REGISTRYINDEX, "Player");
g_clientlua.lua_getfield(-1, "Func2");
g_clientlua.lua_getfield(LUA_GLOBALSINDEX, "Func1");
g_clientlua.lua_call(0, 1);
g_clientlua.lua_call(1, 1);
if (g_clientlua.lua_isnil(-1))
return retn;
g_clientlua.lua_getfield(-1, "Table1");
if (g_clientlua.lua_isnil(-1))
return retn;
g_clientlua.lua_getfield(-1, "value1");
if (g_clientlua.lua_isnil(-1))
return retn;
retn = (int)g_clientlua.lua_tointeger(-1);
}

Объект clientlua — это объект, который в основном позволяет мне вызывать метод, который вызывает его эквивалент функции lua_ * и заполняет параметр указателя lua_state переменной-членом, которая является указателем на состояние lua.

Каждый раз, когда я называю это, он жалуется на то, что я вызываю утечку из стека lua. Чтобы решить эту проблему, я попытался добавить lua_pop(3) до конца, но потом просто вылетает моя программа без сообщения об ошибке, поэтому я предполагаю, что делаю что-то не так.

У кого-нибудь есть слова мудрости для меня? Какая-то потеряна здесь. Я сомневаюсь, что вышеупомянутый код даже написан правильно, как бы я написал вышеупомянутый вызов lua в C?

4

Решение

Вам нужно позвонить Func1 прежде чем пытаться получить Func2 как Func2 исходит из таблицы, которая Func1 возвращает (а не из глобальной таблицы).

Тогда вам нужно позвонить Func2 и посмотреть Table1 в этом возвращаемом значении и т. д.

Какую жалобу на «утечку стека» вы получаете? Если вы вызываете эту функцию непосредственно из C, тогда да, вы должны быть уверены, что все, что вы положили в стек lua ​​(не для потребления вызывающей стороной и т. Д.), Извлечено из стека lua, прежде чем вы вернетесь.

2

Другие решения

GetNumber функция выполняет не то же самое, что фрагмент кода lua, который вы собираетесь использовать. конкретно GetNumber получает значение "Func2" из реестра, в то время как ваш фрагмент Lua получает значение "Func2" из таблицы, возвращенной Func1(), Если вы не уверены, что registry.Player.Func2 == Func1().Func2 является всегда правда, ваша версия C ++ не будет иметь такого же поведения.

Давай сломаться Func1():Func2().Table1.value1 в более явные шаги, чтобы помочь с переводом C:

  1. Получить функцию, связанную с _G.Func1
  2. Вызови эту функцию и верни стол
  3. Получить функцию, связанную с "Func2" из возвращенной таблицы в шаге 2
  4. Вызовите эту функцию и передайте в качестве аргумента таблицу из шага 2. Получите еще одну таблицу в качестве результата

Я обнаружил, что полезно отслеживать, что стек содержит в качестве побочного комментария при выполнении операций:

int GetNumber()
{
// Func1()
gclientlua.lua_getfield(LUA_GLOBALSINDEX, "Func1");     // Func1
g_clientlua.lua_call(0, 1);                             // {}

// Func2( {} )
g_clientlua.lua_getfield(-1, "Func2");                  // {}, Func2
g_clientlua.lua_insert(-2);                             // Func2, {}
g_clientlua.lua_call(1, 1);                             // {}

if( g_clientlua.lua_type(-1) != LUA_TTABLE )
{
g_clientlua.lua_pop(1);
return 0;
}

// {}.Table1
g_clientlua.lua_getfield(-1, "Table1");                 // {}, {}(Table1)
if( g_clientlua.lua_type(-1) != LUA_TTABLE )
{
g_clientlua.lua_pop(2);
return 0;
}

// tonumber( Table1.value1 )
g_clientlua.lua_getfield(-1, "value1");                 // {}, {}(Table1), value1
int retn = g_clientlua.lua_tointeger(-1);
g_clientlua.lua_pop(3);
return retn;
}

Заметить, что GetNumber выскакивает все аргументы, которые он помещает в стек перед возвратом. Это гарантирует, что GetNumber выходит из стека луа так, как он был найден. Вероятно, это можно автоматизировать с помощью RAII, если вы используете C ++.

0

По вопросам рекламы [email protected]