【问题标题】:Add members dynamically to a class using Lua + SWIG使用 Lua + SWIG 将成员动态添加到类
【发布时间】:2012-10-30 20:31:49
【问题描述】:

此 Lua 代码创建一个表并动态添加一个新成员。运行这个我可以按预期在屏幕上得到"hello"

foo = {}
foo.x = "hello"
print(foo.x)

但现在我正在使用 SWIG 将一些 C++ 类绑定到 Lua。 为此,在test.i(SWIG 模块文件)中,我创建了一个像这样的简单类:

%module test

%inline
%{

class Foo
{
public:
  Foo() { X = 0; }
  void SetX(int x) { X = x; }
  int GetX() { return X; }
private:
  int X;
};

%}

然后我写了一个这样的测试 Lua 代码:

obj = test.Foo()
obj:SetX(5)
print("Number: " .. obj:GetX())

按预期运行并获取"Number 5"。问题是当我动态地向我的 SWIG 绑定对象添加一个新成员并尝试访问它时,如下所示:

obj.Y = 7
print("Number: " .. obj.Y)

我收到此错误消息:

"attempt to concatenate field 'Y' (a nil value)"

是否可以在使用 SWIG 绑定的对象上动态添加新成员?是否有一些选项无需移动到另一个 Lua 绑定库?

【问题讨论】:

    标签: c++ scripting lua swig


    【解决方案1】:

    SWIG 不为其对象使用表格;它使用用户数据。毕竟那些对象是 C++ 对象,需要存储 Lua 代码不应该接触到的 C++ 数据。

    而且我不会费心寻找“另一个 Lua 绑定库”;几乎所有他们都使用用户数据,Lua 代码明确无法修改(为了提供完全做到这一点的能力)。

    然而,这并不意味着你不能作弊。

    您始终可以将您从 C++ 代码中获取的对象包装到您自己的 Lua 表中,该表将有一个元表,用于将未知调用转发给 C++ 对象。执行此操作的代码如下所示:

    local function WrapObject(cppObject)
    
        local proxy = {}
    
        local wrapper_metatable = {}
    
    function wrapper_metatable.__index(self, key)
        local ret = rawget(self, key)
        if(not ret) then
            ret = cppObject[key]
            if(type(ret) == "function") then
                return function(self, ...)
                    return ret(cppObject, ...)
                end
            else
                return ret
            end
        else
            return ret
        end
    
    end
    
    
        setmetatable(proxy, wrapper_metatable)
        return proxy
    end
    

    返回的代理对象是一个可以设置键和值的 Lua 表。当你得到一个值时,比如调用一个函数,它会查看表中是否设置了该值。如果没有,它会尝试从您包装的 C++ 对象中获取它,该对象将通过 its 元表。

    如果您的 C++ 类使用其他元函数(如 __add__sub__tostring 等),则需要扩展此元表。

    【讨论】:

    • 感谢您这么快的回答!现在我使用了您发布的 WrapObject 函数。我创建了一个对象:“obj = test.Foo()”,然后包装:“wobj = WrapObject(obj)”,但是现在,当我调用“wobj:GetX()”时,我收到以下错误消息:“GetX ( arg 1),预期 'Foo *' 得到了 'table'"。有什么想法吗?
    • @Dani:抱歉,忘记了 self 参数。这应该会更好。
    • 有效!惊人的! :-) 我对 Lua 元表了解不多,并且我已经搜索了很多这样的解决方案。我相信这是不可能的......谢谢!
    猜你喜欢
    • 2022-11-29
    • 1970-01-01
    • 2011-07-05
    • 2011-01-05
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多