【问题标题】:Adding member function to a C++ class bound to Lua将成员函数添加到绑定到 Lua 的 C++ 类
【发布时间】:2012-01-11 16:44:20
【问题描述】:

我一直在研究如何将 C++ 类绑定到 Lua 以在游戏引擎中使用,但遇到了一个有趣的问题。我一直在关注这个网站上的教程:http://tinyurl.com/d8wdmea。看完教程,才发现他建议的代码如下:

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);

只会将 pounce 函数添加到 Monster 的特定实例。所以我将他建议的脚本更改为以下内容:

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);

但是,当我调用 pounce 函数时,脚本会中断。经过进一步测试,我能够成功调用 pounce 函数的唯一方法是将该函数作为 Monster 类的静态成员调用(该函数的代码保持不变):

Monster.pounce(badguy,5,1);

从语法上讲,badguy:pounce(5,1) 是正确的,但没有正确调用函数。我只是做错了什么,还是这是 lua 和 c++ 之间绑定的限制/我如何绑定这两种语言?

【问题讨论】:

  • 这里只看到Lua,这个问题真的和C++有关系吗,还是这完全是一个LUA问题?
  • 是否打印“in pounce 功能”调试消息?在代码的每一行之间添加更多调试打印,以找出崩溃的确切位置,我们将能够为您提供更好的帮助。
  • 你还能添加脚本是如何中断的吗?你得到什么样的错误消息和回溯?它是完全进入pounce 函数还是出现nil 值错误等?
  • @MooingDuck 是的,Monster 类是用 C++ 定义的,并且使用静态方法包装器绑定到 Lua 到成员函数。我的一个想法是,因为 pounce 函数没有在 C++ 中定义,而我在 Lua 中创建它,所以它不能作为静态函数工作。
  • @Deco 不,“in pounce 函数”在像成员函数一样被调用时不会打印。当我尝试将 pounce 函数作为成员函数调用时,脚本会中断。

标签: c++ lua lua-c++-connection


【解决方案1】:

认为我理解这个问题,并且可能对解决方案有所了解。从技术上讲,lua Monster 'class' 和 C++ Monster 类之间没有联系。当您在给定的 lua 对象上调用 lua“成员函数”时,它不知道 C++ 中的特定 Monster 对象。如果要调用 C++ 对象的非静态方法,则不能使用 lua C 函数来执行此操作。您需要在 lua 对象的某个位置附加一个用户数据,该对象具有指向 C++ 对象的指针(要非常小心对象的生命周期 - 您必须使用完整的用户数据并使用 C 函数覆盖 lua 中的 __gc 破坏C++ 对象)。在这种情况下,您可以在需要此用户数据的 Monster 类上声明一个私有静态 C++ 方法,然后使用给定的参数转换指针并调用此特定 C++ 怪物对象的非静态成员函数。 (我希望我能理解你的问题,并且我的答案写得足够清楚。)

【讨论】:

    【解决方案2】:

    当你写作时

    function Monster:pounce(howhigh, bonus)
    

    这是一个快捷方式

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

    显然是这样称呼的

    Monster.pounce(badguy, 5, 1);
    

    正如你所做的那样是有道理的。

    但是您想做一些不同的事情:从您的 C++ 模块中,您会得到一个名为 Monster 的表。您不想操作此表本身,因为它(仅?)包含一个名为 create 的条目,一个 monster 的构造函数。

    我必须承认我没有完全得到你链接的代码,但是假设一个怪物的方法被一个元表访问,你可以在那个元表中插入方法pounce

    【讨论】:

      【解决方案3】:

      不可能直接使用其所有参数调用您的 C-Object/Function。你必须在你的 Lua-State 中注册一个 C-Function。这个函数必须是这样的:

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

      这个函数只接收 Lua-State 作为参数。 Luafunction 调用的所有参数都放在 lua 堆栈上。然后你必须从堆栈中弹出并用它调用你的 C++ 方法。

      函数的注册非常简单,只需两行代码:

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

      您可以在“programming in lua”一书的this chapter 中找到更多相关信息

      你想做的事情,实现一个 Lua 对象有点复杂,因为你必须注册一个元表来创建一个 Lua 对象,但你的 Lua 到 C 接口仍然是解释类型的函数。

      您还可以在 Roberto Ierusalimschy 的 chapter 28一书中倾向于实现 Lua 对象

      希望对你有帮助

      【讨论】:

      • RTFQ,在你告诉他们给 RTFM 之前,拜托。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 2015-12-08
      • 2018-10-04
      相关资源
      最近更新 更多