C# LuaInterface 类运算符

我在C#中使用LuaInterface,并将一些自定义的C#类“导出”以供Lua使用。例如:

local myVector = Vector2(10, 100)

但是,当我想要使用类运算符时,例如在此示例中:

local v1 = Vector2(1, 1)
local v2 = Vector2(2, 2)
local v3 = v1 + v2

我会得到以下错误:尝试在本地“p1”(用户数据值)上执行算术运算

C#版本的类确实具有+运算符:

public static cVector2 operator +(cVector2 vector1, cVector2 vector2)
    {
        return new cVector2(vector1.X + vector2.X, vector1.Y + vector2.Y);
    }

我知道您应该使用Lua元表,并为*运算符添加一个函数,例如“__mul”。但是,LuaInterface会自动执行此操作吗?如果没有,我该如何自动化此过程?

点赞
用户501459
用户501459

但是 LuaInterface 能自动做到这点吗?

不行。您可以通过以下方式看到:

for k,v in pairs(getmetatable(v1)) do
    print(k,v)
end

您会发现没有 __add 这个元方法。

如果不能,我该如何自动化它?

您需要修改 LuaInterface 的源代码,寻找 operator+ 方法并添加 __add 元方法。目前它还没有做到这一点。

鉴于您已经可以访问类型代理(因为您通过 import_type 导入了类型),故您可以访问 operator+,它是类型的静态方法。

local v3 = Vector2.op_Addition(v1,v2)

要使用 v1 + v2,您需要修改 Vector2 对象实例使用的元方法,但这需要创建该类型的实例:

local v1 = Vector2(1,1)
getmetatable(v1).__add = function(a,b) return Vector2.op_Addition(a,b) end

这会影响所有实例使用的元方法,因此您只需要进行一次操作即可。现在您可以编写:

local v2 = Vector2(2,2)
local v3 = v1 + v2

因为您需要修改对象的元方法,所以使代码更简洁可能有些难。如果您修改 C# 代码以确保您的类具有默认构造函数(即没有参数),则可以创建一个包装器来完成 import_type

function luanet.import_type_ex(typename)
    local T = luanet.import_type(typename)
    local mt = getmetatable(T())
    local function gethandler(name) return T[name] end
    local function addmethod(metamethodName, handlerName)
        local foundHandler, handler = pcall(gethandler, handlerName)
        if foundHandler then mt[metamethodName] = handler end
    end
    addmethod('__add', 'op_Addition')
    addmethod('__sub', 'op_Subtraction')
    addmethod('__mul', 'op_Multiply')
    addmethod('__div', 'op_Division')
    return T
end

您可以将其扩展为其他运算符。请注意,LuaInterface 如果尝试访问不存在的成员会抛出异常(而不是返回 nil),因此我们必须使用 pcall 包装访问处理程序的尝试。

有了这个,您可以编写:

Vector2 = luanet.import_type_ex('YourNamespace.Vector2')
local v1 = Vector2(10)
local v2 = Vector2(20)
local v3 = v1 + v2

当然,这也适用于具有重载运算符的其他类型。

LuaInterface 有些混乱。在 Lua 的世界中,有一些类似它的项目,其中 PUC-Rio 的某些人将其作为研究项目做,发布论文,然后放弃了。他们那样做是为了看看自己是否能做到,而不是因为他们真的会用到它。

2014-04-08 21:30:01