作者:克湖泓瑜24 | 来源:互联网 | 2023-09-17 10:08
我正在尝试读取由C ++程序写入文件的结构(我没有源代码)。到目前为止,我一直试图将这种结构读入C#并将其封送处理,但没有成功。
该结构基本上是一组固定长度的字符串,每个字符两个字节。在C ++中,可以将它们声明为TCHAR [8]。
磁盘上的数据如下:
我尝试了下面的C#代码,我知道它们可以成功作为字符串读入值:
public void ReadTwoStringsOfFixedLength()
{
string field1 = string.Empty;
string field2 = string.Empty;
FileReadString(handle,out field1,16);
FileReadString(handle,out field2,16);
}
public static void FileReadString(BinaryReader reader,out string outVal,int length)
{
var mem = new MemoryStream();
outVal = string.Empty;
byte b = 0;
for (int i = 0; i {
b = reader.ReadByte();
if (b != 0) mem.WriteByte(b);
}
outVal = Encoding.GetEncoding(1252).GetString(mem.ToArray());
}
但是,我真正想做的是使用c#结构,因为此数据在C ++中表示为结构(并包含我在此未描述的其他字段)。
我已经尝试了各种方法,这些方法都基于我在StackOverflow上阅读的答案来尝试封送数据,但没有一种方法产生我想要的结果。在大多数情况下,要么字符串编码不正确,要么以内存异常告终,要么仅以每个字段的第一个字符告终(可能是由于空终止?)
这是我的代码:
void Main()
{
byte[] abBuffer = handle.ReadBytes(Marshal.SizeOf(typeof(MyStruct)));
//access data
GCHandle pinnedPacket = GCHandle.Alloc(abBuffer,GCHandleType.Pinned);
var atTestStruct = (MyStruct)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(),typeof(MyStruct));
}
[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi),Serializable]
struct MyStruct
{
[MarshalAs(UnmanagedType.ByValTStr,SizeCOnst= 16)]
string Field1 // Resulting value = "F";
[MarshalAs(UnmanagedType.ByValTStr,SizeCOnst= 16)]
string Field2; // Resulting value = "F"
}
请注意,我也尝试使用CharSet.Unicode
,但是结果字符串是乱码。
任何帮助修复该代码的人将不胜感激。
我认为您需要在CharSet = CharSet.Unicode
上设置StructLayout
。
ASCII / ANSI中的
46 00 69 00
被视为单个字符和空终止符。 documentation显示CharSet.Unicode
是两字节字符(例如您正在显示的字符)所必需的。
SizeConst
的值也必须是字符数,而不是字节。