.net - 从托管代码调用具有固定缓冲区的非托管 DLL(编码问题)

标签 .net unmanaged stringbuilder streamwriter

我有一个非托管 DLL,它通过预分配缓冲区从 .NET 调用以填充到非托管 DLL 中(根据 Pass C# string to C++ and pass C++ result (string, char*.. whatever) to C#)。

我的非托管函数具有以下原型(prototype):

myFunc(char* a_inBuf,  int a_InLen, 
       char* a_outBuf, int* a_pOutLen, 
       char* a_errBuf, int* a_pErrLen);

因此,我在托管代码中声明方法如下:

public static extern int myFunc(
  [In, MarshalAs(UnmanagedType.LPStr)] string inputXml, int inputLen,
  [MarshalAs(UnmanagedType.LPStr)] StringBuilder outputXml, ref int outputLen,
  [MarshalAs(UnmanagedType.LPStr)] StringBuilder errorXml, ref int errorLen);

在调用 myFunc 之前,我创建了两个 StringBuilder:

StringBuilder outputXml = new StringBuilder(100);
StringBuilder errorXml  = new StringBuilder(100);

调用 myFunc 后,我使用两个 StringBuilder 将它们写入一个 XML 文件(每个 StringBuilder 一个)

using (StreamWriter writer = new StreamWriter("OutputXmlFile.xml", false, Encoding.UTF8))
{
  writer.Write(outputXml.ToString());
  writer.Close();
}

由于输入也是 UTF8,因此输出应以 UTF8 编写。但不幸的是,StringBuilder 使用 UTF16 编码。 outputXmlerrorXml 的内容也以 UTF8 编码填充到非托管 DLL 中。不应更改此行为。写入文件时,StringBuilder 中包含的特殊字符写入不正确。

我如何告诉 StringBuilder 内容实际上是 不是 UTF16 而是 UTF8?


编辑: the answer provided by Polynomial表示使用xmlWriter 写入文件。但实际上,写入只是用于调试输出。在正常的应用程序运行中,程序内部直接使用outputXmlerrorXml的内容。因此,任何关于使用特殊 XML 处理类的提示都没有用。

实际问题是从 StringBuilder 中获取正确的字符串(或将它们转换为正确的字符串)。

最佳答案

您无法说服 pinvoke 编码器从 utf8 转换。它将采用 utf-16 或系统默认代码页,并始终转换为 utf-16。

没关系,自己动手就好。相反,声明类型为 byte[] 的参数。调用前创建长度合适的数组,调用后使用Encoding.UTF8.GetString()转换。

关于.net - 从托管代码调用具有固定缓冲区的非托管 DLL(编码问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8034479/

相关文章:

java - 将索引处的所有字符(在 StringBuilder 中)替换为另一个字符串

Scala 字符串生成器

.Net WinForms TabControl 窃取关注表单激活

c# - 错误 : Can't choose dates on a DatePicker that fall outside a floating VSTO Add-In

c# - CLR 如何知道静态字段是否已被初始化?

c++ - Windows Embedded Compact(Windows CE)程序的事后分析

java - 我的 String 和 StringBuilder 未在控制台中显示输出

c# - 在 FlowLayoutPanel 中插入用户控件

c# - 如何找出这些 dwFlags 常量的值?

c# - 将字符指针从 C# 传递到 C++ 函数