简体   繁体   中英

C# marshaling non-ASCII string?

I'm developing an online game which has to trade packets with a C++ server. I'm doing it using the Unity 5 engine. My life was getting hard when I started to write the packet structures in the C# code using Marshaling. 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.

I have this C# struct:

[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. The problem is when some non-ascii character is sent on Text. The Marshal fails the conversion and assign null to Text. If I manually change this non-ascii character to any ascii character before converting the packet buffer the marshal works. 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. 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.

I've done a test: it works even in the case that m_Text is null.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM