У меня есть класс, завернутый в swig и зарегистрированный с помощью lua. Я могу создать экземпляр этого класса в lua-скрипте, и все работает нормально.
Но скажем, у меня есть экземпляр класса, созданный в моем коде на C ++ с вызовом нового X, и у меня есть la lua_state L с функцией в нем, которую я хочу вызвать, которая принимает один аргумент, экземпляр X ... Как мне вызвать эту функцию. Вот (часть) рассматриваемого кода (я пропустил обработку ошибок):
main.cpp
class GuiInst;
extern "C"
{
int luaopen_engine (lua_State *L);
}
int main()
{
GuiInst gui=new GuiInst;
lua_State *L=luaL_newstate();
luaopen_engine(L); //this is swigs module
int error=luaL_loadfile(L,"mainmenu.lua")||
lua_pcall(L, 0, 0, 0);
lua_getglobal(L,"Init");
//Somehow push gui onto lua stack...
lua_pcall(L, 1, 0, 0));
lua_close(L);
}
mainmenu.lua
function Init(gui)
vregion=gui:CreateComponent("GuiRegionVertical");
end
На данный момент все, что я обнаружил, что может сработать, - это предоставить некоторые функции из файла cpp, сгенерированного swig, и вызвать это. Это плохо по нескольким причинам ... Это не сработает, если у меня несколько модулей, и мне пришлось бы изменить спецификацию привязки по умолчанию в файле swig (используя -DSWIGRUNTIME =).
Я добавляю в main.cpp следующее
extern "C"
{
struct swig_module_info;
struct swig_type_info;
int luaopen_engine (lua_State *L);
swig_module_info *SWIG_Lua_GetModule(lua_State* L);
void SWIG_Lua_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type, int own);
swig_type_info *SWIG_TypeQueryModule(swig_module_info *start,swig_module_info *end,const char *name);
}
//and then to push the value...
SWIG_Lua_NewPointerObj(L,gui,SWIG_TypeQueryModule(SWIG_Lua_GetModule(L),SWIG_Lua_GetModule(L),"GuiInst *"),0);
Это получает указатель на модуль, затем указатель на тип, а затем вызывает функцию swigs для его регистрации. Было неразумно копаться в файле, который не должен быть удобочитаемым человеком (так написано в верхней части файла) и является просто НЕПРЕРЫВНЫМ! (но это работает!)
Конечно, есть лучший способ выполнить то, что я пытаюсь сделать.
PS с точки зрения высокого уровня, я хочу, чтобы lua не пересчитывал компоненты Gui, которые создаются Object Factory в GuiInst, на случай, если я ошибаюсь. Я впервые раскрываю функциональные возможности языка сценариев, за исключением некоторых очень простых (и не связанных с swig) модулей Python, поэтому я готов прислушаться к совету.
Спасибо за любой совет!
Ответ на комментарий RBerteig
Конструктор GuiInst # определен как закрытый при запуске swig, чтобы lua не создавал его экземпляры, так что для меня это не сработает. Я пытался предотвратить следующее (в lua):
r=engine.GuiRegionVertical()
r:Add(engine.GuiButton())
который вызовет "g = new GuiButton", затем зарегистрирует его в GuiRegionVertical (который по разным причинам должен хранить указатель), затем вызовет "delete g", и GuiRegionVertical останется с висящим указателем на g.
Я подозреваю, что на самом деле должно произойти то, что GuiRegionVertical :: Add (GuiButton *) должен увеличить счетчик ссылок GuiButton *, а затем деструктор GuiRegionVertical должен уменьшить количество ссылок всего его содержимого, хотя я не уверен, как это должно покончить с глотком.
Это устранило бы необходимость в частных конструкторах, фабрике объектов Gui и неприятных внешних модулях.
Я поступаю неправильно?
Спасибо.