C#封送非ASCII字符串?

时间:2015-04-09 13:06:22

标签: c# string struct ascii marshalling

我正在开发一个必须用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)的编码?

非常感谢非常的想法。

1 个答案:

答案 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为空的情况下也能正常运行。