如何在 c# dllimport 中指定 c++ Variant 返回类型

Posted

技术标签:

【中文标题】如何在 c# dllimport 中指定 c++ Variant 返回类型【英文标题】:How to specify a c++ Variant return type in a c# dllimport 【发布时间】:2017-04-21 09:33:12 【问题描述】:

我在 dll 中有一个 C++ 函数:

VARIANT __stdcall CallBlah(LPCSTR sA, LPCSTR sB, LPCSTR sC, LPCSTR sD, LPCSTR sE, LPCSTR sF)

    char *srtnstring = NULL

    ... do stuff ...

    _bstr_t bstrt(srtnstring);
    return _variant_t(bstrt)

我正在尝试在一个 c# 应用程序中使用它,但我遇到了 Variant 返回类型的问题。我的 c# 导入是:

[DllImport("MyDll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr callBlah(
   string A,
   string B,
   string C,
   string D,
   string E,
   string F);

但是当我运行 c# 应用程序时,我得到了一个不平衡的堆栈异常。 dllImport c# 签名的返回类型应该是什么?

提前致谢。

【问题讨论】:

您可以将VARIANT* 编组为IntPtr,但不确定您是否真的可以编组副本。 如果您可以更改 C++ 代码,那么将变体替换为更简单的类型会容易得多。 封送它为object 这是第 3 方 dll,所以我无法更改它。如果我确实将返回时间更改为对象,我会得到 PInvoke restriction:cannot return variants. 那么我建议最好的方法是用另一个互操作友好的 DLL 包装损坏的 DLL。 【参考方案1】:

首先,您应该在 C# 端使用 StringBuilder 而不是字符串。其次,您应该在 C# 中创建与 c++ VARIANT 兼容的类,然后将其编组为对象。

【讨论】:

我看不到如何创建兼容的类,因为它是一个变体,因此可以容纳任何东西。 你在这里:msdn.microsoft.com/en-us/library/windows/desktop/… 这就是为什么你不应该使用这种类型。您应该阅读 C# 中的 COM,因为 VARIANT 是 COM 类型。 @Steveip 这个答案是假的。忽略它。 我的回答怎么是假的?

以上是关于如何在 c# dllimport 中指定 c++ Variant 返回类型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 DLLImport 将字符串从 C# 传递到 C++(以及从 C++ 到 C#)?

如何在 COM 事件源和处理程序中指定“事件类型”?

如何以编程方式在 C# 中指定单向绑定?

如何在 DPC++ 编译器选项中指定 C++ 标准版本?

如何使用 qmlRegisterType 在 QML 中指定 c++ 类型?

如何在C#中获取连接字符串中指定的Mongo数据库