2013-12-08 69 views
1

我正在努力與兩個dimensonal固定字節數組的用途。我必須在C#中轉換類似大小的pascal字符類型。我必須在此數組中有一些字符值。訪問二維固定字節數組

我聲明這就像公共固定字節C10VAFT [14 * 20];

我不知道這個數組是否只是一個大小爲280的D數組,或者它是一個二維數組,因爲我無法獲得我的內涵值因爲我得到了一系列的Byte。

感謝 阿肖克

這裏的代碼。 這是一個帕斯卡結構

CREC10 = RECORD 
     C0RT : INTEGER; 
     C0KEY1 : INTEGER; 
     C10VAFT : ARRAY [0..13] OF PACKED ARRAY [0..19] OF CHAR; 
     C10VH1H : PACKED ARRAY [0..19] OF CHAR; 
     C10VH2H : PACKED ARRAY [0..19] OF CHAR; 
     C10VH3H : PACKED ARRAY [0..19] OF CHAR; 
     C10MPE1 : PACKED ARRAY [0..14] OF CHAR; 
     C10MPE2 : PACKED ARRAY [0..14] OF CHAR; 
     C10MPE3 : PACKED ARRAY [0..14] OF CHAR; 
     C10MPR1 : PACKED ARRAY [0..14] OF CHAR; 
     C10MPR2 : PACKED ARRAY [0..14] OF CHAR; 
     C10MPR3 : PACKED ARRAY [0..14] OF CHAR; 
     SPARE2 : PACKED ARRAY [0..61] OF CHAR; 
     C10CP : INTEGER[4]; 
     C0BRRP : INTEGER[8]; 
     END; 

吹在C#副本結構。我停留與**元件

public unsafe struct CREC10 
    { 
     public short C0RT;      
     public short C0KEY1; 
     **public fixed byte C10VAFT[14*20];** 
     public fixed byte C10VH1H[20]; 
     public fixed byte C10VH2H[20]; 
     public fixed byte C10VH3H[20]; 
     public fixed byte C10MPE1[15]; 
     public fixed byte C10MPE2[15]; 
     public fixed byte C10MPE3[15]; 
     public fixed byte SPARE2[62]; 
     public UcsdInt4 C0CP; 
     public UcsdInt4 C0BRRP; 

    } 
+0

你可以添加一些你到目前爲止的代碼嗎? –

+0

我想幫忙,但你還沒有問過一個真正的問題。您沒有顯示pascal數據結構,也沒有描述如何使用它。 –

+0

@DavidHeffernan我已經添加了結構。 – user3079498

回答

2

您的問題的原生答案是您無法制作二維固定數組。編譯器不會讓你。 documentation說:

不安全的緩衝區始終是向量或一維數組。

如果你繼續使用unsafefixed,那麼你將需要:

  1. 聲明14個獨立的固定字節數組。
  2. 聲明長度爲14*20的單個固定字節數組,然後手動將其索引到該數組中。

索引會是這樣的:

int arrIndex(int elementIndex, int charIndex) 
{ 
    return (elementIndex*20) + charIndex; 
} 

這確實說明,你必須跳過去使用固定大小的緩衝區的語法障礙。


我認爲,你實際上做的是佈局按照您的帕斯卡爾記錄字節流,並希望轉移到這一個C#結構。並可能回來。在我看來,嘗試在C#中使用相同的佈局是一個錯誤。編譯器不希望你這樣做。不要與它戰鬥。爲結構使用自然的C#佈局,並在自然C#佈局和磁盤佈局之間提供映射。

我想要表達的第一點是您絕對不需要也不想在這裏使用unsafefixed。這些都會讓你的生活變得比需要的更艱難。

首先我要假設你有一個C#Stream實例中的原始數據。如果它來自一個字節流,那麼你會做一個MemoryStream

MemoryStream stream = new MemoryStream(bytes); 

但它其實並不重要。它可以是一個文件流。它只是想成爲一個流。

然後你定義一個C#結構來接收數據。這不需要匹配Pascal數據結構的剛性佈局。使用原生C#類型。例如:

public struct CREC10 
{ 
    public int C0RT; 
    public int C0KEY1; 
    public string[] C10VAFT; 
    public string C10VH1H; 

    public static CREC10 FromStream(Stream stream) 
    { 
     .... 
    } 
} 

我沒有定義所有的字段。足以給你一種風味。我還添加了一個靜態方法,可以從一個流中創建一個新的靜態方法。這可以這樣實現:

public static CREC10 FromStream(Stream stream) 
    { 
     CREC10 result; 
     using (BinaryReader reader = new BinaryReader(stream)) 
     { 
      result.C0RT = reader.ReadInt32(); 
      result.C0KEY1 = reader.ReadInt32(); 
      result.C10VAFT = new string[14]; 
      for (int i=0; i<result.C10VAFT.Length; i++) 
      { 
       result.C10VAFT[i] = Encoding.ASCII.GetString(reader.ReadBytes(20)); 
      } 
      result.C10VH1H = Encoding.ASCII.GetString(reader.ReadBytes(20)); 
     } 
     return result; 
    } 

這確實假定在你的結構中沒有包裝。它看起來好像就是這樣。而且我還假設你的整數是4個字節寬,但也許對於這個有點年邁的Pascal編譯器來說並非如此。無論如何,我相信你知道數據結構的二進制佈局,並可以消除這些細節。

而且您可以編寫一個匹配函數將結構複製到使用相同格式的流中。

如果您嘗試在C#中使用剛性Pascal佈局,您會發現在C#代碼中實際處理數據非常困難。

+0

但是這種結構將超過512字節大小的限制,並且在這種情況下,從數據庫中讀取的數據不會被正確地應用,因爲我通過DLL來修復函數接口。 – user3079498

+0

@ user3079498您的內存中表示不需要與磁盤上的表示相匹配。如果您強制使用C#以與傳統Pascal結構相同的佈局進行維護,您會發現處理數據的過程非常艱難。 –

+0

@ user3079498我的答案現在告訴你,你不能使用2D固定緩衝區。我仍然相信你的方法是錯誤的,但是如果你想堅持下去,我的回答會告訴你如何去做。 –

4

通過使用該decalaration C10VAFT [14×20]你得到的3920的陣列,並且你得到字節的數組,因爲在.NET炭和字節之間的差是 字節= 8比特和焦炭= 2字節(16位),其中一個字節和炭是在C#same thing

多維數組被聲明這樣

char[,] array = new char[14, 20] 

或其是從PASCAL不同

char[][] array = new char[14][] ; 
+0

你也可以用'char [,] array = new char [int size,int size]聲明' – Ilan321

+0

你顯示的不是多維數組。它被稱爲'鋸齒陣列'兩者都不同 –

+0

對不起,我更新了我的答案,但它會工作或者 –