【问题标题】:How to pass string parameters from c++ com to c#?如何将字符串参数从 c++ com 传递给 c#?
【发布时间】:2016-09-19 14:18:09
【问题描述】:

我的 c++ 代码具有这样的参数:

STDMETHODIMP TVinaImpl::test(BSTR Param1)
{
  try
  {
      Param1=(L"test1");
  }
  catch(Exception &e)
  {
    return Error(e.Message.c_str(), IID_IVina);
  }
  return S_OK;
}  

我使用 c++ builder:

当我在 c# 中调用这个 com dll 函数时,它会显示错误:

IntPtr a = new IntPtr();
vina.test(a);

它为空,没有得到值。
如何将变量从 C# 传递给 c++ com 并传回?

【问题讨论】:

    标签: c# c++ com


    【解决方案1】:

    由于Param1 被声明为[in, out] 参数,您需要将其声明为指向BSTR 的指针:STDMETHODIMP TVinaImpl::test(BSTR* Param1)

    此外,您不能简单地将字符串文字分配给 BSTR。正确的方法是使用SysAllocString分配内存:*Param1 = SysAllocString(L"test1");

    【讨论】:

    • 是否有办法避免在 c++ 中使用 SysAllocString?
    • 不幸的是,这是不可能的。 BSTR 由 COM 管理,并且始终需要从其内存分配器中分配。如果不需要自动化兼容性,您可以考虑使用简单的wchar_t*
    • 有没有办法在客户端分配内存(例如在 c# 中)并通过引用 c++ 方法传递参数?
    • 是的,这是可能的。您需要将 Param1 的定义更改为 wchar_t*,如我之前的评论中所述:[in, out, string] wchar_t** Param1
    【解决方案2】:

    我建议您将参数 Param1 声明为 [out, retval]。您没有使用 Param1 作为任何类型的输入。

    STDMETHODIMP TVinaImpl::test(BSTR* Param1)
    {
      try
      {
          *Param1= SysAllocString(L"test1");
      }
      catch(Exception &e)
      {
        return Error(e.Message.c_str(), IID_IVina);
      }
      return S_OK;
    }  
    

    那么当你从 C# 调用函数时,它就是,

    string s = vina.test();
    

    .Net 运行时管理数据从 .Net 到 COM 的编组,反之亦然。

    【讨论】:

    • 你说的对,但是当我想返回多个参数来发送我的函数并返回所有这些参数时,我该怎么做。每个函数只能得到一个返回值。
    猜你喜欢
    • 2011-02-11
    • 2011-09-09
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多