Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#LuaInterface类运算符_C#_Class_Lua_Operators_Luainterface - Fatal编程技术网

C#LuaInterface类运算符

C#LuaInterface类运算符,c#,class,lua,operators,luainterface,C#,Class,Lua,Operators,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 ope

我在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元表,并为“uuu mul”添加一个函数,例如*运算符。但是LuaInterface不是自动做到的吗?如果没有,我怎么能自己实现自动化呢

但是LuaInterface不是自动做到的吗

不需要。您可以通过以下方式自行查看:

for k,v in pairs(getmetatable(v1)) do
    print(k,v)
end
您将不会看到添加元方法

如果没有,我如何自己实现自动化

您必须修改LuaInterface源以查找
操作符+
方法并添加
\u add
元方法。它现在根本不这样做

假设您有可用的类型代理(因为您通过
import\u 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
您可以将其扩展到其他运营商。请注意,如果您尝试访问不存在的成员(而不是返回
nil
),LuaInterface将引发异常,因此我们必须使用
pcall
包装访问处理程序的尝试

有了它,你可以写:

Vector2 = luanet.import_type_ex('YourNamespace.Vector2')
local v1 = Vector2(10)
local v2 = Vector2(20)
local v3 = v1 + v2
当然,这适用于具有重载运算符的其他类型


LuaInterface有点乱。在Lua的世界里也有一些类似的项目,在那里,有人把它作为一个研究项目,然后放弃了它。他们这样做是为了看看是否可以,而不是因为他们真的在使用它。

我很惊讶,8个月后,这一点没有得到回应。我正在添加悬赏,因为您的问题仍然有效。您在错误消息中写入了
p1
。那应该是
v1
?这里显示的任何代码中都没有
p1
。非常好的答案,谢谢。Lua世界中是否有实际使用/仍在开发/标准化的项目?此外,我将尝试您的
import_type_ex
建议。Lua世界中有标准C#接口吗?不,有很多LuaInterface的叉子,但它们添加了太多我从未使用过的随机废话。我只是绕过了LuaInterface的局限性。至于
import\u-type\u-ex
,我注意到我又为
handler
添加了一个不必要的包装器。删除它可以让
addmethod
对一元运算符或二元运算符起作用,所以使用更新的版本。是的,我也注意到了这一点。幸运的是,我有LuaInterface源代码,因此可以根据需要扩展它。您的
import\u type\u ex
运行良好。但是,我不知道如何处理结构,因为该方法需要一个无参数构造函数,而我在C#中的结构中没有这个构造函数。嗯,我可能不得不将我的结构转换成类,但如果可以的话,我宁愿保留它们的结构。另一个问题:添加算术运算符的方法能否处理我在C#中设置的多重组合?像
Coordinate/Coordinate
Coordinate/Dimension
等等,结构总是有一个无参数的构造函数。你不需要添加一个,事实上不能。是的,如果这个组合在C#中有效,它应该是有效的。我不想占用你的时间,但你帮了我很大的忙。那么,当
JASG.Coordinate
是一个结构时,为什么要从您的
local mt=getmetatable(T())
站点获取
“JASG.Coordinate不包含构造函数(.ctor)参数匹配”