Reputation: 41
I have been working on how to bind C++ classes to Lua for use in a game engine, and I have run into an interesting problem. I have been following the tutorial on this website: http://tinyurl.com/d8wdmea. After the tutorial, I realized that the following code he suggested:
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);
Would only add the pounce function to that specific instance of a Monster. So I changed the script that he suggested to the following:
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);
However, when I call the pounce function, the script breaks. After further testing, the only way I was able to successfully call the pounce function was by calling the function as a static member of the Monster class (the code for the function stays the same):
Monster.pounce(badguy,5,1);
Syntactically, badguy:pounce(5,1) is correct, but isnt correctly calling the function. Am I just doing something wrong, or is this a limitation of the binding between lua and c++/how I am binding the two languages?
Upvotes: 4
Views: 1291
Reputation: 4061
When you write
function Monster:pounce(howhigh, bonus)
this is a shortcut for
Monster.pounce = function(self, howhigh, bonus)
So obviously calling this by
Monster.pounce(badguy, 5, 1);
as you did makes sense.
But you want to do something different: From your C++ module you get a table named Monster
. You don't want to manipulate this table itself, as it (only?) contains an entry named create
, a monster
's constructor.
I must admit that I don't completely get the code you linked to, but assuming a monster's method are accessed by a metatable, you could insert the method pounce
in that metatable.
Upvotes: 0
Reputation: 802
I think I understand the question, and may have an idea of the solution. The is technically no link between the lua Monster 'class' and the C++ Monster class. When you call a lua 'member function' on a given lua object, it has no knowledge of the particular Monster object in C++. If you want to call a non-static method of a C++ object you cannot use a lua C-function to do this. You would need to have a user-data somewhere attached to your lua object that has a pointer to the C++ object (be very careful about object lifetimes - you must use full-userdata and override the __gc in lua with a C-function that destroys the C++ object). In this case, you can declare a private static C++ method on the Monster class that expects this userdata, and then casts the pointer and calls the non-static member function for this particular C++ monster object, with the given arguments. (I hope I understand your question, and that my answer is written clearly enough.)
Upvotes: 0
Reputation: 612
it is not possible to call your C-Object/Function directly with all of its parameters. You have to register a C-Function into your Lua-State. This function has to look this way:
static int myfunc (lua_State *L) {
// your code
return X; /* X = number of results */
}
This function receives only the Lua-State as parameter. All the parameters of the Luafunction call laying on the lua stack. You have to pop then from the Stack and Call your C++ method with it.
The registration of a function is quiet simple and done with two lines of code:
lua_pushcfunction(l, myfunc);
lua_setglobal(l, "myfuncnameinlua");
You can find more information about that in this chapter of the Book "programming in lua"
The thing you want to do, implementing an Lua-Object is a bit more complicated, because you have to register a metatable to create a Lua Object but your Lua to C interface are still functions of the explained kind.
You can also lean to implement a Lua-Object in Roberto Ierusalimschy's book on chapter 28
I hope this will help you
Upvotes: -3