c# - MarshalAs(UnmanagedType.LPStr) - 这如何将 utf-8 字符串转换为 char*

标签 c# c++ marshalling

题目基本上就是我想问的:

[MarshalAs(UnmanagedType.LPStr)] - 这如何将 utf-8 字符串转换为 char*?

当我尝试在 c# 和 c++ dll 之间进行通信时,我使用了上面的行; 更具体地说,介于:

somefunction(char *string) [c++ dll]

somefunction([MarshalAs(UnmanagedType.LPStr) string text) [c#]

当我通过 c# 将我的 utf-8 文本 (scintilla.Text) 发送到我的 c++ dll 时, 我在 VS 10 调试器中显示:

  1. c#字符串成功转换为char*

  2. 生成的 char* 在监 window 口中正确反射(reflect)相应的 utf-8 字符(包括韩语中的位)。

这是一个屏幕截图(包含更多详细信息):

ss

如您所见,initialScriptText[0] 返回单个 byte(char): 'B' 和 char* initialScriptText 在 VS 监 window 口中正确显示(包括韩语)。

通过 char 指针,似乎英语被保存为每个 char 一个 byte,而韩语似乎被保存为两个每个 char 的字节数。 (截图中的韩文单词为3个字母,因此节省了6个字节)

这似乎表明每个“字母”都没有保存在相同大小的容器中,而是因语言而异。 (关于类型的可能提示?)

我试图在纯 C++ 中实现相同的结果:读取 utf-8 文件并将结果保存为 char*

这是我尝试读取一个 utf-8 文件并将其转换为 C++ 中的 char* 的示例:

enter image description here

观察:

  1. wchar_t* 转换为 char* 时视觉损失
  2. 由于结果,s8 正确显示字符串,我知道我已经将 wchar_t* 中的 utf-8 文件内容成功转换为 char*
  3. 因为“result”保留了我直接从文件中获取的字节,但我得到的结果与我通过 c# 得到的结果不同(我使用了相同的文件),我得出的结论是 c# marshal 已将文件内容通过一些其他过程进一步将文本变异为 char*

(屏幕截图还显示了我在使用 wcstombs 时的可怕失败)

注意:我使用的是来自 ( http://utfcpp.sourceforge.net/ ) 的 utf8 header

请纠正我在代码/观察中的任何错误。

我希望能够模仿我通过 c# marshal 获得的结果,并且在经历了所有这些之后我意识到我完全被卡住了。有什么想法吗?

最佳答案

[MarshalAs(UnmanagedType.LPStr)] - how does this convert utf-8 strings to char* ?

事实并非如此。托管代码中没有“utf-8 字符串”之类的东西,字符串始终以 utf-16 编码。 LPStr 的编码和编码是使用默认系统代码页完成的。这使得您在调试器中看到韩文字形非常引人注目,除非您使用代码页 949。

如果与 utf-8 的互操作是一项硬性要求,那么您需要在 pinvoke 声明中使用 byte[]。并使用 System.Text.Encoding.UTF8 自己来回转换。使用其 GetString() 方法将 byte[] 转换为字符串,其 GetBytes() 方法将字符串转换为 byte[]。如果可能,请在 native 代码中使用 wchar_t[] 来避免所有这些情况。

关于c# - MarshalAs(UnmanagedType.LPStr) - 这如何将 utf-8 字符串转换为 char*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13289171/

相关文章:

ruby - 从套接字连接导入 Ruby 类?

c++ - 如何制作一个简单的 C++ Makefile

c# - 将指向结构数组指针的指针从 C# 传递到 C++

c# - 更改 mysql 数据库中的值行而不是添加

c# - 将 Razor 与 Jquery 合并以实现自动完成功能

c# - CLI/C++ 和 C# : How to capture C++ exceptions in Release Mode

C# (VS2008) 抑制修饰键的键码,但保留修饰符

android - 从 android 或 ios 上的投币机获取硬币数量

c++ - 是否有利用 move 的 back_inserter 变体?

java - 将非泛型方法转换为泛型方法