【发布时间】:2014-05-28 03:07:15
【问题描述】:
我有一个用 C++ 编写的 COM 组件,我想通过互操作在我的 C# 应用程序中调用它的接口。
我要调用的接口是这样定义的:
C#互操作接口定义:
void ICertainInterface.Func(int cnt, ref string colors)
C++ 定义:
ICertainInterface : IUnknown
{
virtual HRESULT Func(long cnt, BSTR * colors) = 0;
}
我很清楚,接口应该是我的应用程序中具有特定长度的 BSTR 数组。第二个参数 BSTR * colors 假设代表我的字符串数组中的第一个字符串地址。
现在这是我用来从 C# 应用程序调用接口的代码:
ICertainInterface obj = GetInterface();
string[] strArray = new string[4];
strArray[0] = "aaa";
strArray[1] = "bbb";
strArray[2] = "ccc";
strArray[3] = "ddd";
obj.Func(4, ref strArray[0]);
运行应用程序后,出现“尝试读取或写入受保护内存”的错误。如果数组大小仅为 1,则不会发生这种情况。 在我看来,因为字符串数组是 C# 中的托管数据。所以内存分配是不可预测的,一旦我将 strArray[0] 作为对 C++ 接口的引用,该接口将把它作为数组的起始地址,并假设 add by 4 将获得下一个元素的地址,但它不能在 C# 内存分配中也是如此。
我从网上搜索了一些帖子,似乎大多数接口用户“ref string[]”作为指向 C# 数组的指针,但不像这个“ref string”,我只能引用数组中的第一个元素(我什至不知道这是否是正确的做法,因为在 C++ 中,第一个元素地址等同于数组地址。)
此外,我在调用相同接口的 excel VBA 代码中进行了相同的测试:
Dim msColor(4) As String
msColor(0) = "aaa"
msColor(1) = "bbb"
msColor(2) = "ccc"
msColor(3) = "ddd"
Dim obj as ICertainInterface
Set obj = GetInterface();
Call obj.Func(4, msColor(0))
此 VBA 代码完美运行,没有任何错误。
现在我完全不知道如何在我的 C# 应用程序中解决这个问题。有人可以指点我吗?非常感谢。
【问题讨论】: