J'ai une classe qui est enveloppée avec swig, et enregistré avec lua. Je peux créer une instance de cette classe dans un script lua, et tout fonctionne bien. Mais disons que j'ai une instance d'une classe faite dans mon code C++ avec un appel à new X, et j'ai la lua_state L avec une fonction que je veux appeler, qui accepte un argument, une instance de X ... Comment j'appelle cette fonction. Voici (un peu) du code en question (j'ai omis les trucs de gestion des erreurs):Comment puis-je pousser une instance d'une classe C++ encapsulée avec swig sur une pile lua?
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
Au moment tout ce que je ont trouvé que cela peut fonctionner est d'exposer certaines fonctionnalités à partir du fichier cpp généré swig, et appeler cela. C'est mauvais pour quelques raisons ... Cela ne fonctionnera pas si j'ai plusieurs modules et que j'ai dû changer la spécification de liaison par défaut dans le fichier swig (en utilisant -DSWIGRUNTIME =).
j'ajouter ce qui suit à 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);
qui obtient un pointeur sur le module, puis un pointeur vers le type, puis appelle rasades fonction pour l'enregistrer. C'était une chose déraisonnable d'avoir à creuser dans un fichier qui n'est pas supposé être lisible par l'homme (donc ça se trouve en haut du fichier) et c'est juste MESSY! (mais ça marche!)
Sûrement il y a une meilleure façon d'accomplir ce que j'essaie de faire. PS d'un pov de haut niveau ce que je veux, c'est que lua ne recompose pas les composants Gui qui sont créés par Object Factory dans GuiInst, au cas où je m'y prendrais mal. C'est la première fois que j'expose des fonctionnalités à un langage de script en dehors de quelques modules python très simples (et non swig), donc je suis prêt à prendre conseil.
Merci pour votre conseil!
Réponse au commentaire par RBerteig
de contructor de guiinst est #defined à privé lorsque rasade court pour empêcher la construction d'instances lua de celui-ci, de sorte que cela ne fonctionne pas pour moi. Ce que je voulais éviter était la suivante (en lua):
r=engine.GuiRegionVertical()
r:Add(engine.GuiButton())
qui appellerait « g = new guibutton » puis enregistrez-le GuiRegionVertical (qui a besoin de stocker un pointeur pour diverses raisons), puis appelez "supprimer g", et le GuiRegionVertical est laissé avec un pointeur dangling à g. Je soupçonne que ce qui doit vraiment arriver est que GuiRegionVertical :: Add (GuiButton *) devrait incrémenter le nombre de ref de GuiButton *, puis le destructeur de GuiRegionVertical devrait décrémenter les refcounts de tout son contenu, bien que je ne sois pas sûr comment cela devrait être fait avec swig.
Cela supprimerait le besoin pour les constructeurs privés, la Gui Object Factory et les externs méchants.
Est-ce que je vais mal?
Merci.
duplication possible de [SWIG: Lua - Passage d'une instance C++ comme paramètre de fonction lua] (http://stackoverflow.com/questions/9455552/swiglua-passing-ac-instance-as-a-lua-function- paramètre) –
@NicolBolas: Comment cette question peut-elle être un doublon? C'est trois ans de plus que celui-là :). Merci pour le lien tho. – DaedalusFall