2013-12-08 71 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

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