[英]C# marshaling non-ASCII string?
I'm developing an online game which has to trade packets with a C++ server. 我正在开发一个在线游戏,该游戏必须与C ++服务器交换数据包。 I'm doing it using the Unity 5 engine.
我正在使用Unity 5引擎进行操作。 My life was getting hard when I started to write the packet structures in the C# code using Marshaling.
当我开始使用Marshaling用C#代码编写数据包结构时,我的生活变得越来越艰难。 Unity have serious bugs here, but ok for all of the Unity related bugs I'm used to implement any sort of workaround, but this bug I'm facing right now I think it could be some Marshal's limitation.
Unity在这里有严重的错误,但是对于我用来实现任何变通办法的所有与Unity相关的错误都可以,但是我现在面临的这个错误我认为这可能是元帅的局限性。
I have this C# struct: 我有这个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; } }
}
It should works fine when calling Marshal.PtrToStructure. 调用Marshal.PtrToStructure时,它应该可以正常工作。 The problem is when some non-ascii character is sent on Text.
问题是在文本上发送了一些非ASCII字符时。 The Marshal fails the conversion and assign null to Text.
元帅转换失败并为Text分配null。 If I manually change this non-ascii character to any ascii character before converting the packet buffer the marshal works.
如果我在转换数据包缓冲区之前手动将此非ascii字符更改为任何ascii字符,则封送工作。 The point is that I canno't format all the packets server-side to avoid send these non-ascii characters, I actually need them to display the correct string.
关键是我无法在服务器端格式化所有数据包以避免发送这些非ASCII字符,我实际上需要它们显示正确的字符串。 Is there a way to set the encoding of this marshaled string (Text) in its definition?
有没有办法在其定义中设置此封送处理的字符串(文本)的编码?
A ny ideas are appreciated, thanks very much. 感谢您的想法,非常感谢。
I would encode/decode the string manually: 我会手动编码/解码字符串:
[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;
}
}
Note that on set I'm manually adding a final 0 terminator ( m_Text[95] = 0
) to be sure the string will be a correctly-terminated C string. 请注意,在设置时,我手动添加了最后一个0终止符(
m_Text[95] = 0
),以确保该字符串将是正确终止的C字符串。
I've done a test: it works even in the case that m_Text
is null. 我已经做了测试:即使
m_Text
为null,它也可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.