在Lua的活动程序中调用C ++函数 [英] Call C++ Functions in an active program from Lua

查看:104
本文介绍了在Lua的活动程序中调用C ++函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  class Foo 
{
private:
int number = 0;

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

int main()
{
Foo foo;

//加载并执行Lua脚本,使用foo对象

return 0;
}

我如何允许Lua脚本做 foo .setNumber()(最好不要 foo。)?这可能是一个非常简单的问题,但如上所述,Google上的几乎所有信息

我在Linux(Ubuntu)需要在所有平台(Windows和Mac)上编译

b

要滚动您自己的绑定,您应该:


  1. 完全掌握Lua metatables。

  2. 阅读C API上的 Lua编程内容,特别是类。或者,您可以阅读手册,阅读源代码(尤其是API标题),然后进行一些搜索,但这本书可能会节省一些时间。

大致来说,通过创建一个包含指向类实例的指针的Luauserdata,将一个C ++类实例暴露给Lua,并将其传递给Lua脚本。 userdata是一个不透明类型; Lua脚本不能真正做任何事情(除了传递它),除非你给它一个metatable。至少你必须在userdata上实现 __ index 元方法,这允许你的C ++代码拦截尝试索引userdata并返回有意义的东西,而 __ gc metamethod,它允许你的C ++代码在相应的Lua用户数据被垃圾回收时删除暴露的C ++对象。



您创建一个名为 createFoo 的函数,创建一个 Foo 实例,将指针作为userdata包装,



当用户运行 foo时, .setNumber ,您的C ++ __ index 元方法使用userdata和字符串setNumber调用。这取决于你返回什么,这决定了在Lua脚本中 foo.setNumber 求值。你需要 foo.setNumber 来计算 lua_CFunction ,它需要一个 Foo userdata作为它的第一个参数,所以你的类方法可以从Lua中惯用的调用(即 foo:setNumber(12) $ c> foo.setNumber(foo,12))。



这是一个非常低级别和手动的过程,它会最终创建一个库/模板/宏任何为你做样板。此时,您可能需要评估存在的无数 C ++绑定库。但是,感谢漏报抽象法 ,了解如何执行此操作是一个非常好的主意手动优先。


I'm not sure if my question makes any sense, but I certainly know it is near impossible to get the results from Google. Firstly, what I do not want. I don't want to call some function that prints "hello world" or adds two numbers together, I want to load a Lua script from a C++ program, but allow the script to modify variables of the C++ program, using functions. For example, imagine I have a C++ program like this:

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

How could I allow the Lua script to do foo.setNumber() (preferably without foo.)? This may be a very simple question, but as mentioned above, almost all information on Google when searching "Call C++ Function from Lua" assume there is no program, but just a .cpp/hpp file with some functions that you want to call.

I'm on Linux (Ubuntu), but the program needs to compile on all platforms (Windows and Mac)

解决方案

This is asked here fairly regularly.

To roll your own binding you should:

  1. Master Lua metatables completely.
  2. Read the Programming in Lua stuff on the C API, particularly the part on classes. Alternatively you can read the manual, read the source (API headers especially), and do some googling, but the book will probably save you some time.

Broadly, you expose a C++ class instance to Lua by creating a Lua "userdata" containing a pointer to the class instance and passing this to the Lua script. A userdata is an opaque type; the Lua script can't actually do anything with it (other than pass it around) unless you give it a metatable. At the very least you must implement the __index metamethod on the userdata, which allows your C++ code to intercept attempts to index the userdata and return something meaningful, and the __gc metamethod, which allows your C++ code to delete the exposed C++ object when the corresponding Lua userdata is garbage collected.

For instance, you create a function called createFoo which creates a Foo instance, wraps the pointer as a userdata, applies a metatable implementing __index to it, and returns it to the Lua script.

When the user runs foo.setNumber, your C++ __index metamethod is called with the userdata and the string "setNumber". It's up to you what you return and this determines what foo.setNumber evaluates to in the Lua script. You want foo.setNumber to evaluate to a lua_CFunction which expects a Foo userdata as its first parameter, so that your class methods can be called idiomatically from Lua (i.e. foo:setNumber(12), which is syntax sugar for foo.setNumber(foo, 12)).

It's a very low level and manual process, and once you get the hang of it you're going to end up create a library/templates/macros whatever to do the boilerplate for you. At that point you may want to evaluate the myriad C++ binding libraries that exist. However, thanks to the Law of Leaky Abstractions it's a very good idea to learn to do this manually first.

这篇关于在Lua的活动程序中调用C ++函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆