C# C封送非ASCII字符串? 我正在开发一个在线游戏,它必须与C++服务器交换数据包。我用的是Unity 5引擎。当我开始使用封送处理在C代码中编写数据包结构时,我的生活变得越来越艰难。Unity在这里有严重的bug,但是对于所有与Unity相关的bug,我都习惯于实现任何一种解决方法,但是我现在面临的这个bug,我认为它可能是一些元帅的限制

C# C封送非ASCII字符串? 我正在开发一个在线游戏,它必须与C++服务器交换数据包。我用的是Unity 5引擎。当我开始使用封送处理在C代码中编写数据包结构时,我的生活变得越来越艰难。Unity在这里有严重的bug,但是对于所有与Unity相关的bug,我都习惯于实现任何一种解决方法,但是我现在面临的这个bug,我认为它可能是一些元帅的限制,c#,string,struct,ascii,marshalling,C#,String,Struct,Ascii,Marshalling,我有一个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(Unman

我有一个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时,它应该可以正常工作。问题是在文本上发送某些非ascii字符时。封送处理未通过转换,并将null分配给文本。如果在转换数据包缓冲区之前手动将此非ascii字符更改为任何ascii字符,封送处理将起作用。关键是,我无法在服务器端格式化所有数据包以避免发送这些非ascii字符,我实际上需要它们显示正确的字符串。有没有办法在定义中设置此封送字符串文本的编码


非常感谢您的宝贵意见。

我将手动对字符串进行编码/解码:

[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;
    }
}
注意,在集合中,我手动添加一个最终的0终止符m_Text[95]=0,以确保该字符串将是一个正确终止的C字符串


我做了一个测试:它甚至在m_文本为空的情况下也能工作。

您能更具体地说明非ascii字符的含义吗?是8位字符>=128,可以在当前代码页中表示为重音拉丁字母,还是通用UNICODE字符,如数学符号和韩文字母?您定义的字符集是Ansi;我不确定在非ASCII字符的情况下会发生什么…@MartinLiversage抱歉搞砸了。此非ascii字符为8位,但大于等于128。此字符的值正好为0xE3。有什么线索吗?谢谢。这是不可能的,一个Ansi字符串可以使用所有256个可能的代码,而0xE3并不特殊。通常翻译成ã,取决于你住在哪里。获取null值太奇怪了,您需要获得一个异常才能实现。不管真正的问题是什么,你还没有接近诊断它。请记住,CharSet.Ansi永远不会正确,web服务器不会说出您的系统区域设置,您需要byte[]并使用正确的编码。@HansPassant谢谢您的评论。那么,我应该认为这可能是另一个与Unity相关的bug吗?哦,天哪,我对他们太厌倦了:有时候我会很想用SDL2来代替团结呵呵=[