x6h*_*ius 7 c# c++ unicode utf-8
LPUTF8StrC# 中的字符串封送处理对我来说根本不起作用。我觉得我无法正确理解它的用例,但是在仔细研究文档并进行各种其他测试之后,我不确定我做错了什么。
首先,陈述我对字符编码的基本(可能不正确)理解以及为什么 C# 需要转换它们,以防出现问题:
\nconst char*和std::string)默认使用单字节字符。您可以使用包含两字节字符的字符串,但只有在您选择使用时才会使用这些字符串std::wstring(我没有这样做)。\\xhh,其中hh是字节的十六进制编码。例如。"\\xF0\\x9F\\xA4\\xA0"相当于“”。const char*并不意味着它不是由 Unicode 字符组成。给我上色"\\xF0\\x9F\\x98\\x92"=>“”因此,对于 C++ 程序,它必须使用const char*指针将字符串公开给 C#,并且 C# 应用程序必须通过将这些字符串转换为宽字符来封送这些字符串。假设我有以下 C++ 函数,为了演示 C# 封送处理,它通过结构体传递数据:
// Header:\nextern "C"\n{\n struct Library_Output\n {\n const char* str;\n };\n\n API_FUNC void Library_GetString(Library_Output* out);\n}\n\n// Source:\nextern "C"\n{\n void Library_GetString(Library_Output* out)\n {\n if ( out )\n {\n // Static string literal:\n out->str = "This is a UTF-8 string. \\xF0\\x9F\\xA4\\xA0";\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n在 C# 中,我这样调用该函数:
\npublic class Program\n{\n [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]\n struct Library_Output\n {\n // This is where the marshaling type is defined.\n // C# will convert the const char* pointer to\n // a string automatically.\n [MarshalAs(UnmanagedType.LPUTF8Str)]\n public string str;\n }\n \n [DllImport("Library.dll")]\n static extern void Library_GetString(IntPtr output);\n\n private static void Main()\n {\n int structSize = Marshal.SizeOf(typeof(Library_Output));\n IntPtr structPtr = Marshal.AllocHGlobal(structSize);\n\n Library_GetString(structPtr);\n \n // Tell C# to convert the data in the unmanaged memory\n // buffer to a managed object.\n Library_Output outputStruct =\n (Library_Output)Marshal.PtrToStructure(structPtr, typeof(Library_Output));\n \n Console.WriteLine(outputStruct.str);\n\n Marshal.FreeHGlobal(structPtr);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n应用程序实际打印出的内容不是将字符串打印到控制台,而是:
\n\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdn\xef\xbf\xbd\nRun Code Online (Sandbox Code Playgroud)\n但是,如果我将封送类型更改为 而UnmanagedType.LPStr不是UnmanagedType.LPUTF8Str,我会得到:
This is a UTF-8 string. \nRun Code Online (Sandbox Code Playgroud)\n这让我感到困惑,因为结构成员字符串封送的文档指出:
\n\n\nUnmanagedType.LPStr:指向以 null 结尾的 ANSI 字符数组的指针。
\nUnmanagedType.LPUTF8Str:指向以 null 结尾的 UTF-8 编码字符数组的指针。
\n
那么 ANSI 字符串封送处理会打印 UTF-8(非 ANSI)字符串,但是 UTF-8 字符串封送处理会打印垃圾吗?为了弄清楚垃圾来自哪里,我查看了打印的数据实际上是什么,它似乎是指针本身的值。
\n要么 UTF-8 封送例程将字符串指针值所在的内存视为字符串本身,要么我误解了有关此过程的一些关键内容。从根本上来说,我的问题是双重的:首先,为什么 UTF-8 封送过程不能正确遵循字符串指针,其次,将 UTF-8 字符串从 C++ 封送到 C# 的正确方法实际上是什么?是为了使用LPUTF8Str,还是别的什么?
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |