Lua: сбой при получении глобальной функции после загрузки файла - PullRequest
0 голосов
/ 19 июля 2011

Я пытаюсь вызвать функцию внутри файла lua с именем test2.lua Это содержимое test2.lua:

function abc(path)
 t = {}
 table.insert(t, "a")
 return t
end

Как видите, он принимает один ввод и возвращает строку.

Вот мой C-код. Это довольно просто. Однако мой вызов getglobal для вызова этой функции не работает ... lua_getglobal говорит, что это не функция, когда я ее тестирую ... Есть причина, почему это так? Разве abc не должна быть глобальной функцией, возвращаемой внутри исходного файла? Почему тогда он находит ноль только для этого глобального?

L = lua_open();
luaL_openlibs(L);
luaL_loadfile(L, "src/test2.lua");

lua_getglobal(L, "abc");

lua_pushstring(L, "coollll");

int error = 0;
if ((error = lua_pcall(L, 1, 1, 0)) == 0)
{
    std::cout << "cool";
}

РЕДАКТИРОВАТЬ:

вызов lua_getglobal приводит к тому, что моя программа нарушает управление независимо от использования loadfile или dofile ... есть идеи, почему?

Программа аварийного завершения lua_getglobal

Ответы [ 2 ]

8 голосов
/ 19 июля 2011

Функция luaL_loadfile() читает, анализирует и компилирует именованный файл Lua.Он не выполняет никакого своего содержимого.Это важно в вашем случае, потому что оператор function abc(path) ... end не имеет видимого эффекта, пока не будет выполнен.Ключевое слово function, как вы его использовали, эквивалентно написанию

abc = function(path)  
  t = {}
  table.insert(t, "a")
  return t
end

В этой форме становится понятнее, что переменной с именем abc фактически не присваивается значение до тех пор, пока код не будет выполнен.

Когда возвращается luaL_loadfile(), он помещает анонимную функцию в верхнюю часть стека Lua, которая является результатом компиляции вашего файла.Вам нужно позвонить, и lua_pcall() сделает свое дело.Замените вашу ссылку на luaL_loadfile() следующим:

if (luaL_loadfile(L, "src/test2.lua") || lua_pcall(L, 0, LUA_MULTRET, 0)) {
    // do something with the error
} 

На этом этапе test2.lua был выполнен и доступны все функции, которые он определил, или другие глобальные переменные, которые он изменил.

ЭтоЭто достаточно распространенная идиома, что функция luaL_dofile() предназначена для загрузки и вызова файла по имени.

В представленном вами коде есть вторая, более тонкая проблема.Функция abc() использует переменную с именем t, но вы должны знать, что t - это глобальная переменная.Вы, вероятно, хотели написать local t = {} в верхней части abc().

3 голосов
/ 19 июля 2011

Недостаточно вызвать luaL_loadfile: это помещает кусок в стек. Либо добавьте luaL_[p]call для выполнения чанка (что делает функцию доступной), либо используйте luaL_dofile.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...