Вы вызываете lua_pop()
для удаления предметов из стека Lua. Для простых функций это может быть совершенно ненужным, так как ядро очистит стек как часть обработки возвращаемых значений.
Для более сложных функций и, в особенности, для кода C, который вызывается в Lua, вам часто нужно выталкивать вещи из стека, чтобы предотвратить неуклонный рост стека.
Функция lua_getglobal()
добавляет один элемент в стек при вызове, который является либо nil
, если глобальный не существует, либо значение именованной глобальной переменной. Наличие копии этого значения в стеке защищает его от сборщика мусора до тех пор, пока оно есть. Это значение должно оставаться в стеке, пока оно используется C-кодом, который его извлекал, потому что, если глобальный был изменен, копия в стеке может быть единственной оставшейся ссылкой.
Таким образом, общие закономерности для использования глобального что-то вроде этих:
void doMyEvent(lua_State *L) {
lua_getglobal(L, "MyEvent");
lua_call(L, 0, 0); /* pops the function and 0 parameters, pushes 0 results */
}
double getGlobalDouble(lua_State *L, const char *name) {
double d;
lua_getglobal(L,name);
d = lua_tonumber(L,1); /* extracts the value, leaves stack unchanged */
lua_pop(L,1); /* pop the value to leave stack balanced */
return d;
}
char *copyGlobalString(lua_State *L, const char *name) {
char *s = NULL;
lua_getglobal(L,name);
if (!lua_isnil(L,-1))
s = strdup(lua_tostring(L,-1));
lua_pop(L,1);
return s;
}
В последнем примере, я осторожен, чтобы скопировать содержимое строки, так как указатель, возвращаемый lua_tostring()
только гарантированно действителен, пока значение остается в стеке. Требуется, чтобы вызывающий абонент copyGlobalString()
отвечал за вызов free()
.
Обратите внимание, что последние выпуски Lua manual включают в себя обозначение вместе с каждой функцией, которая идентифицирует количество потребляемых записей стека, и число нажатых. Это помогает избежать неожиданного роста стека.
+1, стиль комментария Lua в коде на C++? :-) –
@nick ... лицоpalm! Теперь его лучше ;-) – RBerteig
Эй! Спасибо за помощь. И еще один вопрос: в чем разница между вызовом lua_call (L, 0, 0); и lua_pop (L, 1); для удаления ФУНКЦИЙ? Я имею в виду, почему вы использовали lua_call (L, 0, 0) вместо использования lua_pop (L, 1)? – Morpheus