4 votes

Ajout d'une fonction membre à une classe C++ liée à Lua

J'ai travaillé sur la manière de lier des classes C++ à Lua pour les utiliser dans un moteur de jeu, et j'ai rencontré un problème intéressant. J'ai suivi le tutoriel de ce site Web : http://tinyurl.com/d8wdmea . Après le tutoriel, j'ai réalisé que le code suivant qu'il proposait :

local badguy = Monster.create();
badguy.pounce = function(self, howhigh, bonus)
    self.jumpbonus = bonus or 2;
    self:jump(howhigh);
    self:rawr();
end
badguy:pounce(5, 1);

Cela ajouterait seulement la fonction de bondissement à cette instance spécifique d'un monstre. J'ai donc changé le script qu'il a suggéré par le suivant :

function Monster:pounce(howhigh, bonus)
    print("in pounce function");
    print(bonus);
    self.jumpbonus = bonus or 2
    self:jump(howhigh);
    self:rawr();
end
local badguy = Monster.create();
badguy:pounce(5,1);

Cependant, lorsque j'appelle la fonction pounce, le script se casse. Après d'autres tests, la seule façon dont j'ai pu appeler avec succès la fonction pounce était d'appeler la fonction en tant que membre statique de la classe Monster (le code de la fonction reste le même) :

Monster.pounce(badguy,5,1);

Syntaxiquement, badguy:pounce(5,1) est correct, mais n'appelle pas correctement la fonction. Est-ce que je fais quelque chose de mal, ou est-ce une limitation de la liaison entre lua et c++/la façon dont je lie les deux langages ?

0voto

Nathan Wiebe Points 746

I pensez à Je comprends la question, et j'ai peut-être une idée de la solution. Techniquement, il n'y a aucun lien entre la "classe" Monster lua et la classe Monster C++. Lorsque vous appelez une "fonction membre" lua sur un objet lua donné, elle n'a aucune connaissance de l'objet Monster particulier en C++. Si vous voulez appeler une méthode non statique d'un objet C++, vous ne pouvez pas utiliser une fonction C de lua pour le faire. Vous devez avoir une donnée utilisateur quelque part attachée à votre objet lua qui a un pointeur vers l'objet C++ (faites très attention aux durées de vie des objets - vous devez utiliser une donnée utilisateur complète et remplacer le __gc dans lua par une fonction C qui détruit l'objet C++). Dans ce cas, vous pouvez déclarer une méthode C++ statique privée sur la classe Monster qui attend ces données utilisateur, puis convertit le pointeur et appelle la fonction membre non statique pour cet objet monstre C++ particulier, avec les arguments donnés. (J'espère avoir compris votre question, et que ma réponse est écrite assez clairement).

0voto

mkluwe Points 1573

Quand vous écrivez

function Monster:pounce(howhigh, bonus)

c'est un raccourci pour

Monster.pounce = function(self, howhigh, bonus)

Alors évidemment, appeler ça par

Monster.pounce(badguy, 5, 1);

comme vous l'avez fait a du sens.

Mais vous voulez faire quelque chose de différent : A partir de votre module C++, vous obtenez une table nommée Monster . Vous ne voulez pas manipuler cette table elle-même, car elle contient (seulement ?) une entrée nommée create , a monster Le constructeur de l'entreprise.

Je dois admettre que je ne comprends pas tout à fait le code que vous avez cité, mais en supposant que les méthodes d'un monstre sont accessibles par une métatable, vous pourriez insérer la méthode pounce dans cette métatable.

-3voto

knowledge stacker Points 522

Il n'est pas possible d'appeler directement votre objet/fonction C avec tous ses paramètres. Vous devez enregistrer une fonction C dans votre état Lua. Cette fonction doit ressembler à ceci :

static int myfunc (lua_State *L) {
  // your code
  return X;  /* X = number of results */
}

Cette fonction ne reçoit que le Lua-State comme paramètre. Tous les paramètres de l'appel de la Luafunction se trouvent sur la pile lua. Vous devez les extraire de la pile et appeler votre méthode C++ avec.

L'enregistrement d'une fonction est très simple et se fait en deux lignes de code :

lua_pushcfunction(l, myfunc);
lua_setglobal(l, "myfuncnameinlua");

Vous pouvez trouver plus d'informations à ce sujet dans ce chapitre du livre " programmation en lua "

L'implémentation d'un objet Lua est un peu plus compliquée, car vous devez enregistrer une métatable pour créer un objet Lua, mais votre interface Lua-C est toujours constituée de fonctions du type expliqué.

Vous pouvez aussi apprendre à implémenter un Lua-Object dans le livre de Roberto Ierusalimschy sur chapitre 28

J'espère que cela vous aidera

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X