访问二维固定字节数组

时间:2013-12-08 09:22:58

标签: c# pascal

我正在努力使用两个固定字节数组。我必须在C#中使用类似的大小转换一个pascal Char类型。我必须在这个数组中有一些字符值。

我将此声明为公共固定字节C10VAFT [14 * 20];

我不知道这个数组是否只是一个大小为280的D数组,或者它是一个二维数组,因为我无法得到我的内涵值becoz我得到了Byte系列。

由于 阿肖克

这里的代码。 这是一个pascal结构

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;

blow是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;

    }

2 个答案:

答案 0 :(得分:4)

通过使用这个decalaration C10VAFT [14 * 20]你得到一个3920的数组,你得到一个字节数组,因为.net中字符和字节之间的区别是 byte = 8bits和char = 2bytes(16bits),与PASCAL不同,其中A字节和char是same thing

在C#中,多维数组声明为

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

A jagged array

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

答案 1 :(得分:2)

您问题的原生答案是您无法制作二维固定数组。编译器不允许你。 documentation说:

  

不安全的缓冲区总是向量或一维数组。

如果您要继续使用unsafefixed,则需要:

  1. 声明14个单独的固定字节数组。
  2. 声明一个长度为14*20的固定字节数组,然后手动索引。
  3. 索引将是这样的:

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

    这确实说明了你必须跳过使用固定大小缓冲区的语法障碍。


    我认为你实际上正在做的是根据你的Pascal记录布置一个字节流,并希望将其转换为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#代码中实际处理数据非常困难。