我正在开发一个必须用C ++服务器交换数据包的在线游戏。我正在使用Unity 5引擎。当我开始使用Marshaling在C#代码中编写数据包结构时,我的生活变得艰难。 Unity在这里有严重的错误,但是对于我用于实现任何类型的解决方法的所有Unity相关错误都没问题,但是我现在面临的这个错误我认为这可能是Marshal的一些限制。
我有这个C#结构:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MSG_SendNotice : IGamePacket
{
public const PacketFlag Opcode = (PacketFlag)1 | PacketFlag.Game2Client;
private PacketHeader m_Header;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 96)]
public string Text;
public PacketHeader Header { get { return m_Header; } }
}
调用Marshal.PtrToStructure时应该可以正常工作。问题是在Text上发送了一些非ascii字符。 Marshal未通过转换并将null赋值给Text。如果我在转换数据包缓冲区之前手动将此非ascii字符更改为任何ascii字符,则编组工作。关键是我无法格式化服务器端的所有数据包以避免发送这些非ascii字符,我实际上需要它们来显示正确的字符串。有没有办法在其定义中设置此编组字符串(Text)的编码?
非常感谢非常的想法。
答案 0 :(得分:0)
我会手动编码/解码字符串:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
public byte[] m_Text;
public string Text
{
get
{
return m_Text != null ? Encoding.UTF8.GetString(m_Text).TrimEnd('\0') : string.Empty;
}
set
{
m_Text = Encoding.UTF8.GetBytes(value ?? string.Empty);
Array.Resize(ref m_Text, 96);
m_Text[95] = 0;
}
}
注意,在set上我手动添加一个最终的0终结符(m_Text[95] = 0
),以确保该字符串是一个正确终止的C字符串。
我已经完成了测试:即使在m_Text
为空的情况下也能正常运行。