将托管字符串封送到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
来解决这个问题。但我不明白为什么会这样!
欢呼
这是因为在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。