如何将c++成员方法和成员变量与Lua C API绑定

How do you bind C++ member methods and member variables with the Lua C API?

本文关键字:Lua API 绑定 变量 成员 c++ 成员方法      更新时间:2023-10-16

我目前所做的所有谷歌搜索都出现了非常接近的东西,但只是不太适合我想要做的。

让我用最基本的方式来描述:

  • 假设你有一个c++类

    class A
    {
    public:
        int Method();
        int Variable;
    };
    
  • 现在假设您实例化了A* Foo;

  • 现在假设您有一个.lua文件,其中包含以下3行函数:

    function Test()
        local n = Foo:Method();
        Foo.Variable = 0;
        local m = Foo.Variable;
    end
    

如何将对象A*绑定到lua,使所有这些事情都是可行的?

伪代码方面,我的第一次尝试是这样的,部分来自复制粘贴的例子:

  1. 在一个只被调用一次的函数中,不管a的实例有多少:
    • create newmettable (MT)
    • pushvalue(-1)(我真的不明白这个)
    • setfield(-2, "__index")
    • pushc函数,带有静态版本的方法,可以从checkudata中解包a *指针
    • setfield(-2, "Method")
  2. 在为每个实例调用的init函数中,例如Foo:
      使用newuserdata创建指向Foo的指针
  3. setmetatable(MT)
  4. setglobal with Foo使lua名称可用
  5. 在main的测试函数中:
    • 用上面提到的3行.lua调用一个测试函数,通过全局名称

执行此操作时,Foo:Hide();成功调用我的静态函数,该函数成功解包指针并调用其成员Hide()。

到目前为止一切顺利:Method()。

然后我尝试支持。variable访问。每个人似乎都在说再次使用元表,这次覆盖__index和__newindex,并使它们成为一种通用的Get/Set,其中您支持某些键作为有效的变量链接,例如if(key == " variable ") variable = val;

问题在于如何把这两件事结合起来。一旦你用一个对Variable有效的getter/setter覆盖了__index/__newindex, Method()调用就不再调用Method()静态函数,而是进入你绑定的__index函数。

说了这么多,如何支持这个看似基本的用例组合呢?

实际的代码片段会比纯理论的喋喋不休更受欢迎。

提示:请只使用基本的C API,而不是第三方的东西。

Method()调用不再调用Method()静态函数,而是进入你所绑定的__index函数。

如果键存在于表中,就先返回键,否则就用getter/setter