4

我想将一个派生自纯虚拟 C++ 类的类的 Lua 对象传递给一个期望纯虚拟类的 C++ 对象的函数。我怎样才能做到这一点?

我是 lua 和 luabind 的新手,所以请耐心等待。

在 C++ 中:

struct A {
  virtual void foo() = 0;
};

void do_something(A* a) {
  a->foo();
}

在 Lua 中:

class 'MyA' (A)
....
function MyA:foo()
  print('hi')
end

再次在 C++ 中:

... // somehow create an instance of MyA class and named myA
    // How? 
    // Maybe the result of a call to "MyA()"?

do_something(myA);
4

4 回答 4

2

抱歉,我不会直接回答您提出的问题,而是会根据个人经验提供一些建议:

如果您是Lua新手,您应该认真考虑在原始 Lua API中编写您的第一个绑定,并且不要使用这种面向对象的布局。至少你会明白到底发生了什么

Lua API 本身使用起来很舒服。它不会产生任何额外的开销,您可以完全控制正在发生的事情。Luabind 库开发目前有点陈旧(但看起来它恢复了活力)。

您应该考虑是否真的需要在 Lua 端,尤其是在 C++ 端模仿从 C++ 类派生。这样的事情对于 Lua 来说并不那么自然,并且需要显着的开销来实现。此外,在 C++ 中,您隐藏了您正在对另一种语言进行非本地调用的事实。除非有充分的记录,否则这是性能问题的潜在来源。

几年前我开始使用 Lua 时,我曾经使用与您相同的方式编写绑定,使用 Luabind,并模仿从 C++ 对象派生。现在我使用纯 Lua API 和简单的过程(相对于面向对象)跨语言接口。我对结果很满意。

于 2009-04-30T05:57:39.950 回答
2

请参阅LuaBind 文档中的第10.1节。您基本上为 LuaBind 类提供了一个简单的 C++ 包装器,它充当底层 Lua 实现的传递。请注意此文档中的以下内容:

virtual void f(int a) 
{ 
    call<void>("f", a); 
}

call("f", a) 将调用 Lua 'f' 函数,传入参数 a。

于 2009-04-29T21:39:21.863 回答
2

您必须创建一个实现纯虚函数的 C++ 类,然后调用 Lua 代码。实现太复杂了,不能在这里扔。

基本伪代码:

// C++
struct LuaA : public A
{
  LuaA(const std::string &luacode)
    : myLuaHandler(luacode)
  {
  }

  virtual void foo()
  {
    myLuaHandler.call("MyA:foo()");
  }
}

该示例非常高级,但它旨在表明您想要做的事情并非微不足道。它是你想要真正暴露给你的 Lua 代码的新的“LuaA”。

一般来说,在包装我的 C++ 以接触 Lua 和其他脚本语言时,我更喜欢使用SWIG 。SWIG 确实支持您感兴趣的虚拟方法的这种重载(在 SWIG 用语中称为“导演”),但是应该注意 Lua/SWIG 不支持导演。Java、C#、Ruby、Perl 和 Python 在 SWIG 中都支持导向器。我不确定为什么 Lua 不支持它。

有可能,由于 Lua 不支持继承,因此您想要完成的确切语义根本不可能以您建议的方式实现。

也许其他人对 Lua 方面有更好的答案?

于 2009-04-29T21:14:01.893 回答
1

我将在 C++ 中对纯虚拟类进行子类化,然后可能从 luabind 开始(根据 Aaron 和 lefticus 的解决方案)。如果这个开销太大,我将直接使用 Lua C stack-twiddling API(根据 Alexander)。

因此,这里没有一个答案。稍后我将发布带有结果的评论。

感谢大家!

于 2009-04-30T16:08:54.863 回答