What .NET UnmanagedType is Unicode (UTF-16)?

大憨熊 提交于 2019-12-10 16:36:01

问题


I am packing bytes into a struct, and some of them correspond to a Unicode string. The following works fine for an ASCII string:

[StructLayout(LayoutKind.Sequential)]
private struct PacketBytes
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public string MyString;
}

I assumed that I could do

[StructLayout(LayoutKind.Sequential)]
private struct PacketBytes
{
    [MarshalAs(UnmanagedType.LPWStr, SizeConst = 32)]
    public string MyString;
}

to make it Unicode, but that didn't work (the field value was empty and the other fields had incorrect values, indicating that the byte unpacking was messed up). (Since this field is part of a struct with other fields, which I've omitted for clarity, I can't simply change the CharSet of the containing struct.)

Any idea what I'm doing wrong?

Here is the input (64 bytes, little endian):

31:00:31:00:32:00:33:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

The output should be the Unicode string "1123".


回答1:


I would do this by declaring a nested structure for the string type. The "inner" structure can declare its CharSet. This is similar to the solution on my blog: http://nitoprograms.blogspot.com/2010/02/interop-multidimensional-arrays-of.html

e.g.:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct StringSizeConst32AsString
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    private string Value;

    public static implicit operator string(StringSizeConst32AsString source)
    {
        return source.Value;
    }

    public static implicit operator StringSizeConst32AsString(string source)
    {
        // Note that longer strings would be silently truncated
        //  if we didn't explicitly check this.
        if (source.Length >= 32)
            throw new Exception("String too large for field: " + source);

        return new StringSizeConst32AsString { Value = source };
    }
}



回答2:


Credit to @StephenCleary. My full solution is this:

[StructLayout(LayoutKind.Sequential)]
private struct PacketBytes
{
    [MarshalAs(UnmanagedType.Struct)]
    public UnicodeString MyString;
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
private struct UnicodeString
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string Value;

    public static implicit operator string(UnicodeString value)
    {
        return value.Value;
    }
}


来源:https://stackoverflow.com/questions/2951719/what-net-unmanagedtype-is-unicode-utf-16

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!