在Lua的活动程序中调用C ++函数

时间:2015-07-17 21:10:08

标签: c++ lua

我不确定我的问题是否有意义,但我当然知道从谷歌那里得到结果几乎是不可能的。首先,我所做的想要的。我不想调用打印“hello world”或将两个数字加在一起的函数,我想从C ++程序加载Lua脚本,但允许脚本使用函数修改C ++程序的变量。例如,假设我有一个像这样的C ++程序:

class Foo
{
    private:
        int number = 0;

    public:
        void setNumber(const int& newNumber) {number = newNumber;}
}

int main()
{
    Foo foo;

    //Load and execute Lua script, with foo object

    return 0;
}

我如何允许Lua脚本执行foo.setNumber()(最好没有foo.)?这可能是一个非常简单的问题,但如上所述,Google when searching "Call C++ Function from Lua"上的几乎所有信息都假设没有程序,只有一个.cpp / hpp文件,其中包含一些您要调用的函数。

我在Linux(Ubuntu)上,但该程序需要在所有平台(Windows和Mac)上编译

1 个答案:

答案 0 :(得分:4)

这里有相当规律的问题。

要滚动自己的装订,您应该:

  1. Master Lua metatables完全。
  2. 阅读C API上的Programming in Lua内容,特别是关于类的部分。或者,您可以阅读手册,阅读源代码(特别是API标题),并进行一些谷歌搜索,但本书可能会为您节省一些时间。
  3. 从广义上讲,通过创建一个包含指向类实例的指针并将其传递给Lua脚本的Lua“userdata”,将C ++类实例公开给Lua。 userdata是一个不透明的类型; Lua脚本实际上不能对它做任何事情(除了传递它),除非你给它一个metatable。至少你必须在userdata上实现__index元方法,它允许你的C ++代码拦截索引userdata并返回有意义的东西的尝试,以及__gc metamethod,它允许你的C ++代码当相应的Lua userdata被垃圾收集时,删除暴露的C ++对象。

    例如,您创建一个名为createFoo的函数,它创建一个Foo实例,将指针包装为userdata,将一个metatable实现__index,并将其返回给Lua剧本。

    当用户运行foo.setNumber时,将使用userdata和字符串“setNumber”调用C ++ __index元方法。这取决于你返回的内容,这决定了foo.setNumber在Lua脚本中的评估结果。您希望foo.setNumber评估为期望lua_CFunction userdata作为其第一个参数的Foo,以便可以从Lua(即foo:setNumber(12)以惯用方式调用您的类方法,是foo.setNumber(foo, 12))的语法糖。

    这是一个非常低级别的手动过程,一旦掌握了它,你最终将创建一个库/模板/宏,无论你做什么样的样板。此时,您可能想要评估存在的无数C++ binding libraries。但是,感谢Law of Leaky Abstractions,首先要学会手动执行此操作。