Проблема в том, что ключевое слово require требует очистки всех глобальных переменных, определенных в одном и том же файле.
Я работаю над проектом на C ++. Я использую Луа 5.3. Стиль сценария lua:
1 все коды lua содержат 1 общий файл библиотеки и несколько небольших файлов, каждый из которых действует как функция.
2 при запуске программы общая библиотека lua компилируется и выполняется, оставляя ее глобальные переменные в состоянии lua. Затем небольшие файлы компилируются, а не выполняются.
3 когда программа подходит к какой-то точке, будет вызываться соответствующий маленький файл lua (как я уже сказал, каждый маленький файл - это функция). Глобальные функции и переменные, определенные в общей библиотеке, будут использоваться в небольшом файле lua. Поэтому при запуске программы я компилирую и запускаю общую библиотеку.
4 Я уверен, что использую только 1 lua_State.
Это работало нормально, пока я не решил разделить общую библиотеку на несколько файлов, и использовать "require" в основном файле. При запуске программы основной файл будет скомпилирован и выполнен.
Ни один код не изменился, просто добавьте команду "require". Произошла странная вещь: все глобальные переменные и глобальные функции отсутствуют. Когда глобальная функция вызывается в небольшом lua-файле, возникает ошибка «named nil value».
Затем я провожу эксперимент, удаляю все строки «require» в файле основной библиотеки, и получается, что глобальные функции, определенные в основной библиотеке, работают очень хорошо. Затем мне требуется пустой файл "simple.lua", глобальные функции, определенные в основной библиотеке, отсутствуют, его нельзя вызвать из небольшого файла lua.
Как это объяснить? Как ключевое слово require требует очистки всех глобальных переменных, определенных в одном файле?
в библиотеке lua:
require("simple")
function foo()
return 1+1
end
в небольшом файле lua
return foo()
результат: попытка вызвать нулевое значение (глобальное 'foo')
после удаления "require", библиотека lua:
function foo()
return 1+1
end
результат: ошибки не возникает, возвращается 2
код стороны c ++:
Общая библиотека lua компилируется и исполняется:
int code = luaL_loadbuffer(L, s, strlen(s), "commonlib");
if(code != 0) {
std::string error = lua_tostring(L, -1);
lua_pop(L, 1);
return error;
}
code = lua_pcall(L, 0, 0, 0);
if(code > 0)
{
std::string ret = lua_tostring(L, -1);
lua_pop(L, 1);
return ret;
}
else
return ""; //empty string means no error
lua небольшой файл функции компиляции:
int code = luaL_loadbuffer(L, s, strlen(s), "RULE1");
if(code != 0) {
std::string error = lua_tostring(L, -1);
lua_pop(L, 1);
return error;
}
else
{
return ""; //return empty means no error
}
L в обоих кодах - это одно и то же состояние lua (или оно не будет работать, если убрать «require»). После компиляции небольшая файловая функция в верхней части стека сохраняется в глобальном регистре со ссылочной переменной «ref».
Когда вызывается маленький файл lua, ссылка помещается в стек, используется lua_pcall, ничего особенного.