【问题标题】:Use C++ Component Object Model in C#在 C# 中使用 C++ 组件对象模型
【发布时间】:2012-08-28 06:12:24
【问题描述】:

我正在尝试在 C++ 中构建一个 COM 库,使用 C# 项目进行测试。有些方法需要将字符串返回给调用者。从 C# 调用这些方法时,我得到以下信息:“在位置读取访问冲突......”

这是我的测试项目中的 C++ 代码(除了 VS 2010 ATL 生成的所有东西)

//COMTest.idl
[id(1)] HRESULT Test([out,retval] BSTR* ret);

//Program2.h
STDMETHOD(Test)(BSTR* ret);

//Program2.cpp
STDMETHODIMP CProgram2::Test(BSTR* ret)
{
   BSTR tmp = (BSTR)CoTaskMemAlloc(sizeof(wchar_t) * 2);
   tmp[0] = L'H';
   tmp[1] = L'\0';

   *ret = (BSTR)tmp;
   return S_OK;
}


在 C# 中,我只是从 COM-Tab 中引用了 DLL,关闭了“嵌入互操作类型”,因为它会导致错误,然后运行:

static void Main(string[] args)
{
   COMTestLib.Program2Class instance = new COMTestLib.Program2Class();
   string tmp = instance.Test(); //Where the error occurs

   Console.WriteLine(tmp); //This is not reached

   Console.Read();
}

离开测试方法后发生错误。我从我的 C# 项目中调试了 C++ 代码,并将值放置在正确的位置。如果我尝试返回 0(在 C# 中给出 null),我不会收到错误消息,即使我仍然像示例中那样分配内存。

我无法理解访问冲突所抱怨的地址。它既不是我分配的地址,也不是该方法中使用的任何其他地址。在我看来也很奇怪的是 CoTaskMemAlloc-Function 总是返回第一个字节设置为零 (0x00XXXXXX) 的地址,但这可能只是 COM 的事情。


我没有想法,在任何地方都找不到很多关于这方面的信息(基本的 COM 教程除外)。有人可以帮忙吗?

【问题讨论】:

    标签: c# c++ com


    【解决方案1】:

    BSTR 需要额外的内存(以跟踪字符串 len),因此必须使用 SysAllocString() 函数来分配 BSTR(或使用“smart”BSTR 类之一)。

    所以你的原始代码应该是这样的:

    //Program2.cpp
    STDMETHODIMP CProgram2::Test(BSTR* ret)
    {
       *ret = SysAllocString(L"H");
       return S_OK;
    }
    

    关于 BSTR 的好读物:http://blogs.msdn.com/b/ericlippert/archive/2003/09/12/52976.aspx

    【讨论】:

    • 这行得通,既然你解释了崩溃的实际原因,我把这个作为接受的答案。
    【解决方案2】:

    检查您的 COM 项目和测试项目是否都是 STA。还要检查位数。如果将 BSTR 替换为 LPSTR 会怎样?

    【讨论】:

    • 谢谢,LPSTR 有效!我现在可以继续这个项目,但我仍然想知道为什么 BSTR* 不起作用。为 C# 项目指定 STA 没有任何改变(除了错误框的样式)。这两个项目都是为 x86 构建的,如果这就是您检查位数的意思。
    • BSTR 似乎是固定大小的:msdn.microsoft.com/en-us/library/s9ts558h(v=vs.71).aspx。它可能与 C# 不兼容,但我不确定。 LPSTR 是 Ansi 字符串。
    • 我到处找,但没有找到。再次感谢,现在它可以工作而且很有意义。 :)
    猜你喜欢
    • 2018-09-18
    • 2012-08-24
    • 2010-12-23
    • 2015-05-25
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    相关资源
    最近更新 更多