typ*_*oid 4 c# string struct structure marshalling
我正在尝试将(相当古老的)C++ 字符串消息映射到 C# 结构中,以便在某些新软件中进行处理。我遇到的问题是,当将 C++ 字符串消息映射到 C# 结构时,我丢失了字符(大概是添加了 \0)。
我需要处理的消息数据如下所示:“91000222201”
Where: "91" is one value
"0002" is the next value
"222" is the third value
"01" is the final value
Run Code Online (Sandbox Code Playgroud)
我尝试的第一个结构布局是这样的:
[StructLayout(LayoutKind.Sequential, Size = 11, CharSet = CharSet.Ansi), Serializable]
public struct HeaderPacketStruct
{
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 2)]
public string Value1;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 4)]
public string Value2;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 3)]
public string Value3;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 2)]
public string Value4;
}
Run Code Online (Sandbox Code Playgroud)
它处理了字符串...但产生了以下值:
HeaderPacketStruct.Value1 = "9"
HeaderPacketStruct.Value1 = "000"
HeaderPacketStruct.Value1 = "22"
HeaderPacketStruct.Value1 = "0"
Run Code Online (Sandbox Code Playgroud)
当我将每个字符串上的 SizeConst 增加 +1(以容纳“\0”)时,它开始删除字符:
HeaderPacketStruct.Value1 = "91"
HeaderPacketStruct.Value1 = "0022"
HeaderPacketStruct.Value1 = "01"
HeaderPacketStruct.Value1 = ""
Run Code Online (Sandbox Code Playgroud)
似乎 UnmanagedType.ByValTStr 假设字符串末尾有一个“\0”。有没有办法解决?
顺便说一句,我能够让它与下面结构中的 char[] 一起工作。然而,这个结构更难使用,因为每个值都是 char[] 而不是字符串(在结构内)。必须将 char[] 重新映射到字符串以进行所有处理,这将变得非常痛苦。
StructLayout(LayoutKind.Sequential, Size = 11, CharSet = CharSet.Ansi), Serializable]
public struct HeaderPacketStruct
{
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] Value1;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] Value2;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)]
public char[] Value3;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] Value4;
}
Run Code Online (Sandbox Code Playgroud)
.NET 中的封送处理总是存在错误。字符串编组是双重错误!
我做了一些测试,并且ByValTStr期望最后一个字符,因此'\0'它会读取它并忽略它(但问题是它会读取它!)。你甚至不能通过使用 来作弊LayoutKind.Explicit,因为它会引发两个字段重叠的错误。
你可以做什么:
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)]
private char[] value1;
public string Value1
{
get { return new string(this.value1); }
set { this.value1 = value.ToCharArray(); }
}
Run Code Online (Sandbox Code Playgroud)
这工作正常。