Segfault при попытке вызвать функции lua, определенные в таблице

Я пытаюсь решить эту проблему с ошибкой сегмента, возникающую, когда функция lua, определенная в таблице, вызывается из С++ с использованием luabind. Вот код С++ (заимствованный из В С++, используя luabind, функция вызова, определенная в файле lua?, и http://lua.2524044.n2.nabble.com/How-to-call-a-Lua-function-what-has-былоопределено-в-таблице-td7583235.html ):

extern "C" {
#include <lua5.2/lua.h>
#include <lua5.2/lualib.h>
#include <lua5.2/lauxlib.h>
}


#include <iostream>
#include <luabind/luabind.hpp>
#include <luabind/function.hpp>

int main() {
    lua_State *myLuaState = luaL_newstate();
    luaL_openlibs(myLuaState);
    luaL_dofile(myLuaState, "test.lua");
    luabind::open(myLuaState);

    luabind::object func = luabind::globals(myLuaState)["t"]["f"]; // Line #1
    int value = luabind::call_function<int>(func, 2, 3); // Line #2
    std::cout << value << "\n";
    lua_close(myLuaState);
}

и вот код lua:

t = { f = function (a, b) return a+b end }   -- Line #3

Программа скомпилирована с

g++ test.cpp -I/usr/include/lua5.2 -llua5.2 -lluabind

Вывод программы cpp:

5
Segmentation fault (core dumped)

с обратной трассировкой:

#0  0x00007ffff7bb0a10 in lua_rawgeti ()
   from /usr/lib/x86_64-linux-gnu/liblua5.2.so.0

#1  0x00007ffff7bc27f1 in luaL_unref ()
   from /usr/lib/x86_64-linux-gnu/liblua5.2.so.0

#2  0x0000000000401bb5 in luabind::handle::~handle() ()

#3  0x0000000000401e15 in luabind::adl::object::~object() ()

#4  0x000000000040185c in main ()

Однако я не вижу никакой ошибки, если вместо этого функция lua определена как глобальная, т. е. изменить строку № 3 на чтение

f = function (a, b) return a+b end

и строка № 2 изменена на

int value = luabind::call_function<int>(myLuaState, "f", 2, 3);

Итак, мой вопрос:

  • Почему это происходит?

  • Это правильный способ вызова функций в таблице?

Согласно комментарию @EtanReisner, правильное решение:

Помещение части call_function в блок области видимости решит эту проблему.


person K.Chen    schedule 02.04.2014    source источник
comment
Казалось бы, когда объект luabind выходит за пределы области видимости, деструктор ожидает, что состояние lua будет действительным. Вот выдержка из документации: It's important that all instances of object have been destructed by the time the Lua state is closed. The object will keep a pointer to the lua state and release its Lua object in its destructor.   -  person Retired Ninja    schedule 02.04.2014
comment
Действительно, похоже, это проблема деструктора luabind. Можете ли вы вручную избавиться от ваших объектов luabind, прежде чем вызывать lua_close?   -  person Etan Reisner    schedule 02.04.2014
comment
@Etan: я думаю, что нужно просто изменить luabind::object func = ...; ...; lua_close(luastate) на { luabind::object func = ...; ...; } lua_close(luastate)   -  person Niccolo M.    schedule 02.04.2014
comment
Да, введение такого блока прицела вполне может сработать. Предполагая, что вещи удаляются немедленно при выходе из области видимости и не задерживаются до цикла сборки мусора или чего-то еще.   -  person Etan Reisner    schedule 02.04.2014
comment
Спасибо за ваш комментарий, @EtanReisner. Я проверил, помещая вещи в блок области, ошибка сегмента исчезает.   -  person K.Chen    schedule 03.04.2014