Wil*_*iam 4 .net c# pointers unmanaged
我正在使用 C# 中的 Marshal 类,对此操作的结果有点困惑:
\n\nstring someVal = "Hello There";\nIntPtr ptS = Marshal.StringToHGlobalAnsi(someVal);\nchar* ptsPt = (char*)ptS.ToPointer();\nRun Code Online (Sandbox Code Playgroud)\n\n在立即窗口中查看 ptsPt[0] 后,它包含以下值:\\'\xe6\x95\x88\'
\n\n我猜测这与将托管字符视为 8 位值的方法有关StringToHGlobalAnsi,但当它们实际上是 16 位时。但我不太明白为什么会发生这种情况。
我知道我可以通过将其更改为 来解决这个问题StringToHGlobalUni。但我不明白这是为什么!
干杯
\n这是因为在 C# 中,char是 16 位宽的类型。将字符串StringToHGlobalAnsi 转换为 ANSI,即每个字符 1 个字节。然后查看ptsPt[0],它被解释为包含前两个 ANSI 字符。
这是原始字符串在内存中的样子:
\n\n00 48 00 65 00 6C 00 6C 00 6F 00 20 ...\nRun Code Online (Sandbox Code Playgroud)\n\n这是因为C#字符串是以UTF-16存储的,而上面的“Hello There”就是UTF-16。
\n\n调用后StringToHGlobalAnsi,会分配一块新的内存,其中包含以下字节:
48 65 6C 6C 6F 20 ...\nRun Code Online (Sandbox Code Playgroud)\n\nMarshal.FreeHGlobal(顺便说一句,这意味着您应该在完成后释放它)。
然后,当您得到 achar*时,第一个char指向包含 bytes 48 65,由于小字节序,它实际上意味着0x6548,它代表字符 \xe6\x95\x88。