.NET中的UnmanagedType Unicode(UTF-16)是什么?

4

我正在将字节打包到结构体中,其中一些字节对应于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"。

1
“didn't work”是什么意思?具体哪里出了问题?顺便说一下,依赖“tstring”是一个设计问题——它依赖于遗留的_UNICODE定义。我也认为使用UTF-16是错误的,但这是另外一个故事了。 - Pavel Radzivilovsky
在C#中没有_UNICODE宏,而在C/C++代码中的_UNICODEUNICODE宏并不过时。TStr仅意味着使用由CharSet参数指定的编码。 - Philipp
2个回答

2
我会通过为字符串类型声明一个嵌套结构来实现此功能。 "内部"结构可以声明其字符集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 };
    }
}

不错!看看我的答案,我是怎么实现你的解决方案的。 - Pat

0

感谢 @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;
    }
}

再次说明,如果有人想知道为什么我没有将CharSet放在顶部的结构体中,那是因为在我的实际代码中,该结构体中还有其他需要使用ASCII CharSet的字段。这个解决方案让你可以两全其美。 - Pat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接