【问题标题】:Convert table to Byte array将表转换为字节数组
【发布时间】:2011-11-02 07:01:16
【问题描述】:

我正在尝试将 Lua 表转换为 C# 字节数组。我能够转换为 Double 数组,如下所示:

> require 'CLRPackage'
> import "System"
> tbl = {11,22,33,44}
> dbl_arr = Double[4]
> dbl_arr:GetValue(0)
> dbl_arr:GetValue(1)
> for i=0,3 do Console.WriteLine(dbl_arr:GetValue(i)) end
0
0
0
0
> for i,v in ipairs(tbl) do dbl_arr:SetValue(v,i-1) end
> for i=0,3 do Console.WriteLine(dbl_arr:GetValue(i)) end
11
22
33
44
>

但是,如果我将 dbl_arr 更改为 Byte 数组 (dbl_arr = Byte[4]),则会收到以下错误:(error object is not a string)

我尝试了很多不同的事情,但都没有运气。任何帮助将不胜感激。

更新:

通过这样做,我能够从错误中获得更多信息:

suc,err = pcall(function() byte_arr:SetValue(12,0) end)

现在suc 为假,err 返回以下消息:

SetValue failed
System.ArgumentException: Cannot widen from source type to target type either
   because the source type is a not a primitive type or the conversion cannot
   be accomplished.
at System.Array.InternalSetValue(Void* target, Object value)
at System.Array.SetValue(Object value, Int32 index)

我已经从here 安装了 luaforwindows。它的版本是 5.1.4-45。我正在运行 Microsoft Windows XP Professional Version 2002 Service Pack 3

更新:

这是示例代码以及发生错误的位置

> require 'CLRPackage'
> import "System"
> tbl = {11,22,33,44}
> dbl_arr = Byte[4]
> for i,v in ipairs(tbl) do dbl_arr:SetValue(v,i-1) end <-- Error occurs here

【问题讨论】:

  • dbl_arr 来自哪里?
  • @Nicol - 它只是我创建的一个 Double 数组:dbl_arr = Double[4]
  • 很公平。我的意思是Double[4] 来自哪里。是否使用某种元表来使用 [] 创建对象?
  • @Nicol,这就是 LuaInterface syntax 创建一个新的 Doubles 数组。您描述的元表方法可能是它在幕后完成的方式。
  • MSDN: Array.SetValue 在“当前的Array 不具有精确的一维”时抛出ArgumentException。因此,LuaInterface 中可能存在错误。

标签: .net arrays lua luainterface clrpackage


【解决方案1】:

我怀疑原因是 Console.WriteLine 没有采用 Byte 的重载。

我对 Lua 的了解不够 - 在 C# 中我会调用 GetValue(i).ToString()Convert.ToString(GetValue(i), 16) 并将调用结果提供给 Console.WriteLine

编辑 - 根据评论:

然后你需要转换为字节 - 在 C# 中我会做类似 dbl_arr:SetValue((Byte)0,4)dbl_arr:SetValue((Byte)v,4) 的事情 - 我不知道这是如何完成的 Lua。

编辑 2 - 根据评论:
double 是 8 个字节,Single/float 是 4 个字节。

【讨论】:

  • 这就是响应,我应该提到在运行 for 循环以尝试和SetValue 时发生错误。它会打印全 0,但是当我尝试做类似 dbl_arr:SetValue(0,4) 的事情时,我会收到 (error object is not a string) 消息
  • 是的,不幸的是没有一种投射方式。我尝试做Convert.ToByte(4) 并将其传入,但它仍然失败。我有一种感觉,它将中间结果存储为 Lua“数字”,然后自动将其转换为 C#Double。这是基于该错误我能想出的唯一解释。
  • 请参阅上面@superuser 的评论:这是一个解释,因为 CLR 区分了向量(基于 0 的 1 维)和 1 维数组。
  • 不是双打 8 字节(64 位)每个单打 4 字节(32 位)。
【解决方案2】:

我找到了解决此问题的方法。我会把它贴在这里,虽然我仍然很好奇为什么上面不起作用。

这是解决方法。我基本上创建了一个MemoryStream 并使用WriteByte 函数将值强制为一个字节(由于函数没有重载,它只接受一个字节)。然后我调用ToArrayMemoryStream 获取byte[]

> require 'CLRPackage'
> import "System"
> tbl = {11,22,33,44}
> mem_stream = MemoryStream()
> for i,v in ipairs(tbl) do mem_stream:WriteByte(v) end
> byte_arr = mem_stream:ToArray()
> for i=0,byte_arr.Length-1 do Console.WriteLine(string.format("%d", byte_arr:GetValue(i))) end
11
22
33
44

【讨论】:

    猜你喜欢
    • 2011-03-11
    • 2014-08-08
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2014-10-17
    相关资源
    最近更新 更多