【问题标题】:DLLimport returns gobbledygookDLLimport 返回 gobbledygook
【发布时间】:2014-06-25 14:02:19
【问题描述】:

我在 C++ 头文件中有这个定义

extern "C" __declspec(dllexport) const char* __stdcall GetId(const My_Polyhedron *obj);

在 C# 中有这个

[DllImport("polyhedra.dll", CallingConvention = CallingConvention.Cdecl)]      
        static private extern string GetId(IntPtr obj);

它返回给我 gobbledygook

îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþ2§{€UW @_

在 .net 4.0 中,但在 .net 3.5 中运行良好。

注意:

  1. 我已经在DllImport 中尝试了charset=...(所有可能的设置,例如Charset.Unicode)。

  2. 我试图让它返回IntPtr而不是string,然后使用Marshal.PtrToStringAnsi将它转换回string

  3. 我试过StringBuilder而不是string

上述所有解决方案均无效。

【问题讨论】:

  • 您是否也尝试过在双方都使用 StdCall?
  • @500-InternalServerError 在 .Net 4.0 上,StdCall 无法工作,它会引发 PInvokeStackUnbalance 异常。我尝试关闭运行时异常,关闭后仍然返回goobledygook。在 .Net 3.5 上,Cdecl 和 StdCall 都运行良好,返回我需要的正常字符串。
  • @william007:您可以访问 C++ 代码吗?我建议也以本机模式附加调试器。
  • 这里没有加起来。但无论如何返回这样的字符串肯定是错误的。编组器将在返回的指针上调用CoTaskMemFree。你确定要这样吗?

标签: c# .net .net-4.0 pinvoke


【解决方案1】:

如果您是 C++ 代码的所有者,您可以修改函数,使其将字符串作为输出参数返回:

extern "C" __declspec(dllexport) void __stdcall GetId(
                  const My_Polyhedron *obj, char* result);

然后在 C# 中使用这个导入:

[DllImport("polyhedra.dll", CallingConvention = CallingConvention.Cdecl)]      
static private extern void GetId(IntPtr obj, StringBuilder result);

请注意resultStringBuilder 而不是string
您必须首先通过使 StringBuilder 足够大来分配足够的空间。

这样称呼它:

StringBuilder result = new StringBuilder(1000);
GetId(obj, result);

使用result.ToString() 获取字符串。


有一个 return 属性(它不是真正的属性)指定如何编组返回值:

[return: MarshalAs(UnmanagedType.Bool)]

但我没有在你的代码上尝试过。
也许这有帮助...

【讨论】:

    猜你喜欢
    • 2018-12-02
    • 2011-10-06
    • 2011-05-11
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多