我不确定我的问题是否有意义,但我当然知道从谷歌那里得到结果几乎是不可能的。首先,我所做的不想要的。我不想调用打印“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)上编译
答案 0 :(得分:4)
这里有相当规律的问题。
要滚动自己的装订,您应该:
从广义上讲,通过创建一个包含指向类实例的指针并将其传递给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,首先要学会手动执行此操作。