我需要通过NetworkStream发送一个整数。问题是我只能发送字节。 这就是为什么我需要分割四个字节的整数并发送这些,并在另一端转换回int。如何将int转换为字节数组然后返回?
现在我只需要在C#中使用它。但是对于最后的项目,我需要将这四个字节转换为Lua中的int。
[编辑] 在Lua怎么样?
我需要通过NetworkStream发送一个整数。问题是我只能发送字节。 这就是为什么我需要分割四个字节的整数并发送这些,并在另一端转换回int。如何将int转换为字节数组然后返回?
现在我只需要在C#中使用它。但是对于最后的项目,我需要将这四个字节转换为Lua中的int。
[编辑] 在Lua怎么样?
尝试
BitConverter.GetBytes()
http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx
只需记住的是,在返回数组中的字节的顺序取决于系统的字节序。
编辑: 至于Lua部分,我不知道如何转换回来。你总是可以乘以16来获得按位移4的相同功能。它不是很漂亮,我会想象有一些库或实现它的东西。同样,添加字节的顺序取决于字节顺序,因此您可能需要阅读该字节
也许您可以转换回C#?
调查的BinaryWriter/BinaryReader在类
转换一个int为一个字节数组并显示:BitConverter ...
www.java2s.com/Tutorial/CSharp/0280__Development/Convertaninttoabytearrayanddisplay.htm
整型字节 - 的Visual Basic .NET回答
http://bytes.com/topic/visual-basic-net/answers/349731-integer-byte
如何:将一个字节数组为int(C#编程指南)
由于Nubsis说,BitConverter
是适当的,但没有保证字节顺序。
我有一个EndianBitConverter
类MiscUtil它允许您指定字节顺序。当然,如果您只想为单个数据类型(int
)执行此操作,则只需手动编写代码即可。
BinaryWriter
是另一种选择,并且这个确实保证小的字节顺序。 (同样,如果你想要其他选项,MiscUtil有EndianBinaryWriter
)。
BitConverter是最简单的方法,但是如果你想控制字节的顺序,你可以自己进行位移。
int foo = int.MaxValue;
byte lolo = (byte)(foo & 0xff);
byte hilo = (byte)((foo >> 8) & 0xff);
byte lohi = (byte)((foo >> 16) & 0xff);
byte hihi = (byte)(foo >> 24);
另外.. BitConverter的实现使用不安全和指针,但它很简单。
public static unsafe byte[] GetBytes(int value)
{
byte[] buffer = new byte[4];
fixed (byte* numRef = buffer)
{
*((int*) numRef) = value;
}
return buffer;
}
我更喜欢这种方法,因为BitConverter不会重用现有数组(例如ref byte []) ),并总是创建一个新的数组 - 我想这会在需要完成许多转换时损害性能。 – Libor 2016-06-28 13:42:47
要转换为字节[]:
BitConverter.GetBytes(INT)
http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx
要重新转换为int:
BitConverter .ToInt32(byteArray,offset)
http://msdn.microsoft.com/en-us/library/system.bitconverter.toint32.aspx
虽然我不确定Lua。
如果您担心使用John Skeet的EndianBitConverter。我已经使用它,它可以无缝工作。
C#支持自己的实现htons和ntohs和为:
但他们只对签署INT16,INT32工作,Int64的,这意味着你可能会结束做了很多不必要的工作来使它们工作,如果你使用最高位来除了签名整数之外的任何东西,那么你就搞砸了。去过也做过。 :: tsk :: :: tsk :: Microsoft未在.NET中提供更好的字节顺序转换支持。
以下是Lua中的一些功能,用于将32位二进制补码转换为字节并将四个字节转换为32位二进制补码。可以/应该进行更多检查来验证传入参数是否有效。
-- convert a 32-bit two's complement integer into a four bytes (network order)
function int_to_bytes(n)
if n > 2147483647 then error(n.." is too large",2) end
if n < -2147483648 then error(n.." is too small",2) end
-- adjust for 2's complement
n = (n < 0) and (4294967296 + n) or n
return (math.modf(n/16777216))%256, (math.modf(n/65536))%256, (math.modf(n/256))%256, n%256
end
-- convert bytes (network order) to a 32-bit two's complement integer
function bytes_to_int(b1, b2, b3, b4)
if not b4 then error("need four bytes to convert to int",2) end
local n = b1*16777216 + b2*65536 + b3*256 + b4
n = (n > 2147483647) and (n - 4294967296) or n
return n
end
print(int_to_bytes(256)) --> 0 0 1 0
print(int_to_bytes(-10)) --> 255 255 255 246
print(bytes_to_int(255,255,255,246)) --> -10
这个人很好,虽然我个人从未跟随过卢阿式(......和......)或任务。如果在这种情况下使用,对我来说很好。 – shabunc 2012-01-07 16:20:55
对于Lua,请查看Roberto的struct库。 (罗伯托是Lua的作者之一)。对于特定的案例来说,它比所需要的更普遍,但是交换一个int
的需求不是不太可能需要互换其他简单类型或更大结构。
假设本地字节顺序是在两端上可接受的(这可能是一个坏的假设,顺便),则可以将数字转换为一个4字节整数用:
buffer = struct.pack("l", value)
并再次返回:
值= struct.unpack( “L”,缓冲液)
在两种情况下,buffer
是包含字节一个Lua字符串。如果您需要从Lua访问单个字节值,则string.byte
是您的朋友。
要指定打包数据的字节顺序,改变从"l"
格式,以"<l"
为小端或">l"
为大端。
struct
模块在C语言中实现,必须在Lua可以使用它之前将其编译为一个DLL或同等的平台。也就是说,它被包含在Lua for Windows包含电池的安装包中,这是在Windows系统上安装Lua的常用方式。
如何为Lua端请求一个单独的(但相关的)问题,以便那些答案明显独立于C#答案... – RBerteig 2010-06-24 00:23:11