У меня есть класс, завернутый в 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
На данный момент все, что я нашел, может работать, это показать некоторые функциональные возможности из сгенерированного swig файла cpp и вызвать его. Это плохо по нескольким причинам ... Это не будет работать, если у меня несколько модулей, и мне пришлось изменить спецификацию связывания по умолчанию в файле 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, чтобы зарегистрировать его. Это было неразумно - копаться в файле, который не должен быть читаемым человеком (так сказано в верхней части файла) и просто MESSY! (но это работает!)
Конечно, есть лучший способ выполнить то, что я пытаюсь сделать.
PS от высокого уровня, я хочу, чтобы lua не пересчитывал компоненты Gui, которые созданы Object Factory в GuiInst, на случай, если я ошибаюсь. Я впервые представляю функциональность языку сценариев, за исключением некоторых очень простых (и не очень быстрых) модулей Python, поэтому я готов принять совет.
Спасибо за любой совет!
Ответ на комментарий пользователя RBerteig
Конструктор GuiInst # определяется как приватный, когда swig запускается, чтобы предотвратить его создание lua, так что это не сработает для меня. То, что я пытался предотвратить, было следующим (в луа):
r=engine.GuiRegionVertical()
r:Add(engine.GuiButton())
, который будет вызывать "g = new GuiButton", затем зарегистрировать его в GuiRegionVertical (который должен хранить указатель по разным причинам), затем вызвать "delete g", и GuiRegionVertical останется с висящим указателем на g.
Я подозреваю, что действительно должно произойти, это то, что GuiRegionVertical :: Add (GuiButton *) должен увеличить счетчик ссылок GuiButton *, а затем деструктор GuiRegionVertical должен уменьшить счетчики всех его содержимого, хотя я не уверен как это сделать с помощью swig.
Это избавило бы от необходимости частных конструкторов, Gui Object Factory и неприятных внешних объектов.
Я собираюсь об этом неправильно?
Спасибо.