gpt4 book ai didi

c++ - 使用 Lua + SWIG 将成员动态添加到类中

转载 作者:行者123 更新时间:2023-11-30 02:02:20 24 4
gpt4 key购买 nike

这段 Lua 代码,创建一个表并动态添加一个新成员。运行它,我可以在屏幕上按预期显示 "hello":

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

但现在我正在使用 SWIG 将一些 C++ 类绑定(bind)到 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 绑定(bind)对象时,我尝试访问它,如下所示:

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

我收到此错误消息:

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

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

最佳答案

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

而且我不会费心寻找“另一个 Lua 绑定(bind)库”;几乎所有它们都使用 userdata,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++ 对象中获取它,这将通过它的元表。

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

关于c++ - 使用 Lua + SWIG 将成员动态添加到类中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13326412/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com