Какой .NET UnmanagedType является Unicode (UTF-16)? - PullRequest
4 голосов
/ 01 июня 2010

Я упаковываю байты в структуру, и некоторые из них соответствуют строке Unicode. Следующее работает отлично для строки ASCII:

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

Я предполагал, что смогу сделать

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

, чтобы сделать его Unicode, но это не сработало (значение поля было пустым, а другие поля имели неверные значения, что указывало на то, что распаковка байтов была испорчена). (Так как это поле является частью структуры с другими полями, которые для ясности я пропустил, я не могу просто изменить CharSet содержащей структуры.)

Есть идеи, что я делаю не так?

Вот входные данные (64 байта, младший порядок):

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

На выходе должна быть строка Unicode "1123".

Ответы [ 2 ]

2 голосов
/ 01 июня 2010

Я бы сделал это, объявив вложенную структуру для строкового типа. «Внутренняя» структура может объявить свою CharSet. Это похоже на решение в моем блоге: http://nitoprograms.blogspot.com/2010/02/interop-multidimensional-arrays-of.html

например:.

[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 };
    }
}
0 голосов
/ 01 июня 2010

Кредит @StephenCleary. Мое полное решение таково:

[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;
    }
}
...