【发布时间】:2011-01-05 18:02:29
【问题描述】:
我有一个 COM 组件(在 C# 中),它具有以下接口:
namespace InterOp
{
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.BStr)]
public string name;
[MarshalAs(UnmanagedType.BStr)]
public string surname;
public int age;
}
public interface ITest
{
void SetStringArray(string[] array);
void SetStructArray(MyStruct[] array);
}
public class Test : ITest
{
// string arrays
public void SetStringArray(string[] array)
{
for(int i = 0; i < array.Length; i++)
MessageBox.Show(array[i]); // just do something with the array values
}
// struct arrays
public void SetStructArray(MyStruct[] array)
{
for (int i = 0; i < array.Length; i++)
MessageBox.Show(array[i].name + ", " + array[i].surname + " (" + array[i].age.ToString() + ")");// just do something with the array values
}
}
}
现在我想将数据从 C++ 传递到该 COM 对象。 我这样初始化界面:
HRESULT hr = CoInitialize(NULL);
ITest* pTest = NULL;
hr = CoCreateInstance(__uuidof(Test), NULL, CLSCTX_INPROC_SERVER, __uuidof(ITest), (void**)&pTest);
但我不能将我的数组的引用传递给该方法,因为它需要一个 SAFEARRAY* 数组。我能够使用具有固定大小元素(如 double、int、char 数组)的数组创建 SAFEARRAY,并且使用以下方法可以正常工作:
SAFEARRAY* data = SafeArrayCreate(VT_R8, 1, &bound); //8-Byte-Real, 1 dimension
当然,对于我的用户定义结构,没有“VT_something”,所以我不知道如何创建一个 SAFEARRAY 来解决这个问题。我试过 VT_DISPATCH 和 VT_BSTR 都没有成功。
传递数据的实际方法是这样的:
bool SetStructArrayEx(MyInterOp::MyStruct* array, int arraySize, ITest* comObjectInterface)
{
bool retVal = false;
// Create the safearray environment
SAFEARRAYBOUND bound;
bound.lLbound = 0;
bound.cElements = arraySize;
// Init the safearray
SAFEARRAY* data = SafeArrayCreate(VT_DISPATCH, 1, &bound);
// access the safearray data and copy the original data to it
MyInterOp::MyStruct HUGEP* temp;
HRESULT hr = SafeArrayAccessData(data, (void HUGEP* FAR*)&temp);
if(SUCCEEDED(hr))
{
// finally copy the data
for(int i=0; i<arraySize; ++i)
*temp++ = array[i];
comObjectInterface->SetStructArray(data);
SafeArrayUnaccessData(data);
retVal = true;
}
SafeArrayDestroy(data);
return retVal;
}
...这不起作用(调用 SetStructArray 时出现 Kernel32.dll 中的异常)。
任何想法我错了吗?或者什么会起作用?
谢谢, 马库斯
【问题讨论】: