c# - 将托管字符串编码(marshal)到字符指针 c#

标签 c# .net pointers unmanaged

我正在使用 C# 中的 Marshal 类,对此操作的结果感到有些困惑:

string someVal = "Hello There";
IntPtr ptS = Marshal.StringToHGlobalAnsi(someVal);
char* ptsPt = (char*)ptS.ToPointer();

在即时窗口中查看 ptsPt[0] 后,它包含此值:'Effect'

我猜它与 StringToHGlobalAnsiMethod 将托管字符视为 8 位值有关,但实际上它们是 16 位值。但我不太明白为什么会这样。

我知道我可以通过将其更改为 StringToHGlobalUni 来解决这个问题。但我不明白为什么会这样!

干杯

最佳答案

因为在C#中,char是一个16位宽的类型。 StringToHGlobalAnsi 将字符串 转换为 ANSI,即每个字符 1 个字节。然后查看 ptsPt[0],它被解释为同时包含前两个 ANSI 字符。

这是原始字符串在内存中的样子:

00 48 00 65 00 6C 00 6C 00 6F 00 20 ...

这是因为C#字符串是以UTF-16存储的,上面的“Hello There”就是UTF-16。

在调用 StringToHGlobalAnsi 之后,分配了一 block 新的内存,其中包含这些字节:

48 65 6C 6C 6F 20 ...

(顺便说一句,这意味着您应该在完成后使用 Marshal.FreeHGlobal 释放它)。

然后,当你得到一个 char* 时,指向的第一个 char 包含字节 48 65,由于很少字节序实际上意味着 0x6548,即 stands for the character 效 .

关于c# - 将托管字符串编码(marshal)到字符指针 c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31371859/

相关文章:

c# - 带有两个可为空的日期列的 Linq OrderByDescending

c# - 有没有办法在 C# 中针对 XML/HTML 使用 JQuery 样式选择器?

c# - GUI错误报告

c# - 获取 LINQ 之前的子集 x 元素和 LINQ 之后的 x 元素

c - 读取纺织品并添加到 C 中的链接列表

C - char 数组的内容意外更改

c++ - 指针声明基础(多维数组指针赋值)

c# - 使用 p/Invoke 的 x64 版本的 .net 应用程序崩溃

c# - 测试委托(delegate)是否平等

c# - 从 WinForms 应用程序发送带有附件的电子邮件?