3

I'm trying to convert a Lua Table to a C# Byte array. I was able to get a conversion to a Double array to work as follows:

> 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
>

However if I change the dbl_arr to a Byte array (dbl_arr = Byte[4]), then I get the following error: (error object is not a string)

I've tried a bunch of different things with no luck. Any help would be appreciated.

Update:

I was able to get a bit more information from the error by doing this:

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

Now suc is false and err returns the following message:

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)

I've installed luaforwindows from here. It's version 5.1.4-45. I'm running Microsoft Windows XP Professional Version 2002 Service Pack 3

Update:

This is the example code and where the error occurs

> 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
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
  • Where does `dbl_arr` come from? – Nicol Bolas Aug 23 '11 at 22:02
  • @Nicol - Its just a Double array that I created: `dbl_arr = Double[4]` – SwDevMan81 Aug 23 '11 at 22:19
  • Fair enough. I meant where `Double[4]` comes from. Is it using some kind of metatable to create objects using []? – Nicol Bolas Aug 23 '11 at 22:26
  • @Nicol, That's the [LuaInterface syntax](http://penlight.luaforge.net/packages/LuaInterface/#T5) to create a new array of `Double`s. The metatable method you describe is probably how it's done under the hood. –  Aug 24 '11 at 04:45
  • [MSDN](http://msdn.microsoft.com/en-us/library/kk3bwkb0.aspx): `Array.SetValue` throws an `ArgumentException` when "the current `Array` does not have exactly one dimension". So, there might be a bug in LuaInterface. –  Aug 24 '11 at 22:03
  • @superuser - I would expect the error in that case to be something like `Array was not a one-dimensional array`. I'm still guessing it has to do with a type conversion happening somewhere, but I'm not sure. – SwDevMan81 Aug 25 '11 at 13:12
  • @SwDevMan81, You're probably right. I would hook up the debugger if possible. –  Aug 25 '11 at 15:02
  • Where exactly is the error occurring? It would help if you could post the byte array version and where it's failing. – Jon Skeet Sep 06 '11 at 05:29
  • @Jon - I updated to include the exact code and where the problem occurs – SwDevMan81 Sep 06 '11 at 13:23
  • I would [file a bug report](http://code.google.com/p/luainterface/issues/list) with the LuaInterface team. –  Sep 06 '11 at 23:38

2 Answers2

0

I suspect the reason is that Console.WriteLine does NOT have an overload that takes a Byte .

I don't know enough about Lua - in C# I would call GetValue(i).ToString() or Convert.ToString(GetValue(i), 16) and give the result of that call to Console.WriteLine.

EDIT - as per comment:

Then you need to convert to Byte - in C# I would do something like dbl_arr:SetValue((Byte)0,4) or dbl_arr:SetValue((Byte)v,4) - I don't know how this is done Lua.

EDIT 2 - as per comment:
double is 8 bytes, Single/float is 4 Bytes.

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Thats for the response, I should have mentioned the error occurs while running the for loop to try and `SetValue`. It will print all 0's fine, but when I try and do something like `dbl_arr:SetValue(0,4)`, I get the `(error object is not a string)` message – SwDevMan81 Aug 24 '11 at 12:27
  • Yeah, unfortunetly there isnt a way to cast. I tried doing `Convert.ToByte(4)` and passing that in, but it still fails. I have a feeling its storing the intermediate results as a Lua 'number', which then automatically converts it to a C# `Double`. This is the only explanation I can come up with based on that error. – SwDevMan81 Aug 24 '11 at 21:24
  • see the comment from @superuser above : that would be an explanation since the CLR makes a distinction between a vector (0-based 1 dimension) and a 1-dimensional Array. – Yahia Aug 24 '11 at 22:04
  • Aren't doubles 8 bytes (64bit) each and singles 4 bytes (32bit) each. – Louis Ricci Sep 06 '11 at 15:03
0

I found a workaround for this issue. I'll post it here, although I'm still curious why the above doesn't work.

Here is the workaround. I basically create a MemoryStream and use the WriteByte function to force the value to a Byte (since there is no overload of the function, it only accepts a byte). Then I call ToArray to get the byte[] from the MemoryStream:

> 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
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184