2009-08-01 5 views
9

Может ли кто-нибудь рассказать мне, как правильно использовать функцию lua_pop() в C++.Как правильно использовать функцию lua_pop()?

  • Должен ли я называть это, когда я использую функцию lua_get *()? как.

    lua_getglobal (L, "something");

    lua_pop (L, 1);

или как его использовать? Будет ли сборщик мусора очистить эти вещи после порога? Благодарю.

ответ

20

Вы вызываете 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 включают в себя обозначение вместе с каждой функцией, которая идентифицирует количество потребляемых записей стека, и число нажатых. Это помогает избежать неожиданного роста стека.

+0

+1, стиль комментария Lua в коде на C++? :-) –

+1

@nick ... лицоpalm! Теперь его лучше ;-) – RBerteig

+0

Эй! Спасибо за помощь. И еще один вопрос: в чем разница между вызовом lua_call (L, 0, 0); и lua_pop (L, 1); для удаления ФУНКЦИЙ? Я имею в виду, почему вы использовали lua_call (L, 0, 0) вместо использования lua_pop (L, 1)? – Morpheus

Смежные вопросы