简体   繁体   English

将成员函数添加到绑定到Lua的C ++类中

[英]Adding member function to a C++ class bound to Lua

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. 我一直在研究如何将C ++类绑定到Lua以便在游戏引擎中使用,并且遇到了一个有趣的问题。 I have been following the tutorial on this website: http://tinyurl.com/d8wdmea . 我一直在以下网站上关注该教程: 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. 只会将pounce函数添加到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. 但是,当我调用pounce函数时,脚本会中断。 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): 经过进一步测试后,我能够成功调用pounce函数的唯一方法是通过将该函数作为Monster类的静态成员进行调用(该函数的代码保持不变):

Monster.pounce(badguy,5,1);

Syntactically, badguy:pounce(5,1) is correct, but isnt correctly calling the function. 语法上,badguy:pounce(5,1)是正确的,但没有正确调用该函数。 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? 我是在做错什么,还是lua和c ++之间的绑定限制/我如何绑定这两种语言?

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. 从技术上讲,lua Monster'class'和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++. 在给定的lua对象上调用lua'成员函数'时,它不了解C ++中的特定Monster对象。 If you want to call a non-static method of a C++ object you cannot use a lua C-function to do this. 如果要调用C ++对象的非静态方法,则不能使用lua C函数来执行此操作。 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). 您可能需要将用户数据附加到lua对象的某个地方,该对象具有指向C ++对象的指针(对对象生存期要非常小心-您必须使用完整用户数据,并使用销毁C函数的函数覆盖lua中的__gc C ++对象)。 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. 在这种情况下,可以在需要该用户数据的Monster类上声明一个私有的静态C ++方法,然后强制转换指针并使用给定的参数为此特定C ++ Monster对象调用非静态成员函数。 (I hope I understand your question, and that my answer is written clearly enough.) (希望我能理解您的问题,并且我的回答写得足够清楚。)

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 . 但是,您想做一些不同的事情:从C ++模块中,获得一个名为Monster的表。 You don't want to manipulate this table itself, as it (only?) contains an entry named create , a monster 's constructor. 您不想操作此表本身,因为它(仅?)包含名为create的条目, monster的构造函数。

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. 我必须承认,我并没有完全获得链接到的代码,但是假设一个metatable访问一个Monster的方法,则可以在该metatable中插入pounce方法。

it is not possible to call your C-Object/Function directly with all of its parameters. 不能直接使用其所有参数调用C对象/函数。 You have to register a C-Function into your Lua-State. 您必须将C函数注册到Lua状态。 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. 该函数仅接收Lua-State作为参数。 All the parameters of the Luafunction call laying on the lua stack. Luafunction调用的所有参数都放在lua堆栈上。 You have to pop then from the Stack and Call your C++ method with it. 然后,您必须从堆栈中弹出并使用它调用C ++方法。

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 " 您可以在《 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. 要实现Lua对象,您要做的事情有些复杂,因为您必须注册一个元表才能创建Lua对象,但是Lua to C接口仍然是上述功能。

You can also lean to implement a Lua-Object in Roberto Ierusalimschy's book on chapter 28 您还可以在Roberto Ierusalimschy在第28章的书中倾向于实现Lua-Object。

I hope this will help you 我希望这能帮到您

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM