【问题标题】:Marshalling unmanaged unicode string to .net. High chars replaced with question marks将非托管 unicode 字符串编组到 .net。高字符替换为问号
【发布时间】:2011-10-14 01:40:32
【问题描述】:

这可能是也可能不是 SWIG 问题。

我正在尝试将 std::wstring 按值从 C++ 函数返回到 C#。返回的字符串混合了普通的古英语字符和希伯来字符。英文字符很好,但希伯来字符在某些时候被转换为问号符号。

我正在使用 SWIG 生成编组代码。使用调试器逐步完成所有操作,得到以下 SWIG 代码...

static string CreateWString([MarshalAs(UnmanagedType.LPWStr)]IntPtr cString) {
    string str = System.Runtime.InteropServices.Marshal.PtrToStringUni(cString);
    return str;
}

此时 str 看起来很完美。

接下来,这将返回到 SWIG 生成的 C++ 代码,该代码将 str 作为 void* 返回。

然后 void* 在调用代码中再次变为 .net 字符串。在调用代码中,所有的希伯来字符都是 ?标记。

你知道是什么原因造成的吗?

编辑:

更多信息

一旦 CreateWString 返回到 C++ 调用者,您就可以看到调试器中的指针看起来是一个带有 ? 的 ANSI 字符串。标记在其中。因此,.net 似乎在返回给调用者之前对字符串执行某种转换。听起来对吗?我该如何控制?

编辑 2: 看来我需要在返回类型 CreateWString 上执行 MarshallAs 以阻止 .net 转换为 TCHAR 类型(?)

【问题讨论】:

  • 我不确定是否有足够的代码来解决这个问题。但是,问号表示编码不匹配。确保您实际上使用了正确的编码。 .NET 默认为 Unicode,因此可能会期望使用不同的编码。代码是否有可能使用带有特殊代码页的 Ansi?
  • 这是调用上述 .net 代码的 C++ 代码。 jresult = SWIG_csharp_wstring_callback((&result)->c_str()); return jresult; jresult 是无效的*。它最终以字符串的形式再次出现在 .net 中,但带有 ?字符。问题代码中 str 的值似乎是格式良好的 .net 字符串。
  • @bluedog 你能发布一个可以重现问题的最小项目吗?
  • 你能编辑你的问题并显示回调函数的定义吗?
  • 回调实际上直接指向CreateWString。

标签: c# c++ swig


【解决方案1】:

修改CreateWString定义为:

[return: MarshalAs(UnmanagedType.LPWStr)]
static string CreateWString([MarshalAs(UnmanagedType.LPWStr)]IntPtr cString)

请参阅MarshalAsAttribute 文档中的示例。

【讨论】:

  • 这似乎应该是答案,但仍然没有变化。不过我会继续尝试...
  • 答案是正确的。它起初对我不起作用,因为代码是使用委托调用的。我不得不将代表的签名更改为还包括 [return: MarshallAs...] 部分。
  • 另外,我必须在 C# 的 DllImport 指令中添加 CharSet = CharSet.Unicode
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
相关资源
最近更新 更多