Marshaling管理字符串到char指针c#

时间:2015-07-12 19:47:44

标签: c# .net pointers unmanaged

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

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

在即时窗口查看ptsPt [0]后,它包含了这个值:'效果'

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

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

干杯

1 个答案:

答案 0 :(得分:2)

这是因为在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*时,指向的第一个char包含字节48 65,由于小的字节序实际上意味着0x6548,{ {3}}