2010-06-23 138 views
3

我需要通過NetworkStream發送一個整數。問題是我只能發送字節。 這就是爲什麼我需要分割四個字節的整數併發送這些,並在另一端轉換回int。如何將int轉換爲字節數組然後返回?

現在我只需要在C#中使用它。但是對於最後的項目,我需要將這四個字節轉換爲Lua中的int。

[編輯] 在Lua怎麼樣?

+0

如何爲Lua端請求一個單獨的(但相關的)問題,以便那些答案明顯獨立於C#答案... – RBerteig 2010-06-24 00:23:11

回答

6

嘗試

BitConverter.GetBytes()

http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx

只需記住的是,在返回數組中的字節的順序取決於系統的字節序。

編輯: 至於Lua部分,我不知道如何轉換回來。你總是可以乘以16來獲得按位移4的相同功能。它不是很漂亮,我會想象有一些庫或實現它的東西。同樣,添加字節的順序取決於字節順序,因此您可能需要閱讀該字節

也許您可以轉換回C#?

1

調查的BinaryWriter/BinaryReader在類

1

由於Nubsis說,BitConverter是適當的,但沒有保證字節順序。

我有一個EndianBitConverterMiscUtil它允許您指定字節順序。當然,如果您只想爲單個數據類型(int)執行此操作,則只需手動編寫代碼即可。

BinaryWriter是另一種選擇,並且這個確實保證小的字節順序。 (同樣,如果你想要其他選項,MiscUtil有EndianBinaryWriter)。

8

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; 
} 
+0

我更喜歡這種方法,因爲BitConverter不會重用現有數組(例如ref byte []) ),並總是創建一個新的數組 - 我想這會在需要完成許多轉換時損害性能。 – Libor 2016-06-28 13:42:47

1

要轉換爲字節[]:

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中提供更好的字節順序轉換支持。

2

以下是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 
+0

這個人很好,雖然我個人從未跟隨過盧阿式(......和......)或任務。如果在這種情況下使用,對我來說很好。 – shabunc 2012-01-07 16:20:55

2

對於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的常用方式。

相關問題