Как правильно использовать функцию lua_pop ()? - PullRequest
9 голосов
/ 02 августа 2009

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

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

    lua_getglobal (L, "что-то");

    lua_pop (L, 1);

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

1 Ответ

20 голосов
/ 02 августа 2009

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

...