将托管字符串封送到char指针c#

本文关键字:char 指针 字符串 | 更新日期: 2023-09-27 18:02:23

我正在使用c#中的Marshal类,对这个操作的结果有点困惑:

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

查看当前窗口中的ptsPt[0]后,它包含这个值:' g '

我猜这与StringToHGlobalAnsi方法将托管字符视为8位值有关,但当它们真的是16位时。但我不太明白为什么会这样。

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

欢呼

将托管字符串封送到char指针c#

这是因为在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之后,分配一块新的内存,包含以下字节:

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

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

然后,当您得到一个char*到this时,指向的第一个char包含字节48 65,由于很少的端倒数,它实际上意味着0x6548,它代表字符g。