将托管字符串封送到字符指针 c#
Marshaling managed string to char pointer c#
我正在用 C# 玩 Marshal class,对这个操作的结果有点困惑:
string someVal = "Hello There";
IntPtr ptS = Marshal.StringToHGlobalAnsi(someVal);
char* ptsPt = (char*)ptS.ToPointer();
在立即 window 查看 ptsPt[0] 后,它包含此值:'有效'
我猜这与 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*
时,指向的第一个 char
包含字节 48 65
,由于小字节序实际上意味着 0x6548
, stands for the character 效.
我正在用 C# 玩 Marshal class,对这个操作的结果有点困惑:
string someVal = "Hello There";
IntPtr ptS = Marshal.StringToHGlobalAnsi(someVal);
char* ptsPt = (char*)ptS.ToPointer();
在立即 window 查看 ptsPt[0] 后,它包含此值:'有效'
我猜这与 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*
时,指向的第一个 char
包含字节 48 65
,由于小字节序实际上意味着 0x6548
, stands for the character 效.