我正在努力使用两个固定字节数组。我必须在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;
}
答案 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]
char[][] array = new char[14][] ;
答案 1 :(得分:2)
您问题的原生答案是您无法制作二维固定数组。编译器不允许你。 documentation说:
不安全的缓冲区总是向量或一维数组。
如果您要继续使用unsafe
和fixed
,则需要:
14*20
的固定字节数组,然后手动索引。索引将是这样的:
int arrIndex(int elementIndex, int charIndex)
{
return (elementIndex*20) + charIndex;
}
这确实说明了你必须跳过使用固定大小缓冲区的语法障碍。
我认为你实际上正在做的是根据你的Pascal记录布置一个字节流,并希望将其转换为C#结构。可能又回来了。在我看来,尝试在C#中使用相同的布局是错误的。编译器不希望您这样做。不要打它。为结构使用自然的C#布局,并提供自然C#布局和磁盘布局之间的映射。
我想说的第一点是你明确地不需要也不想在这里使用unsafe
或fixed
。这些都只会让你的生活变得更加艰难。
首先,我将假设您在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#代码中实际处理数据非常困难。