我有一个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
当然,对于我的用户定义的struct,没有“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中的异常)。
我错的任何想法?或者会有什么用?
谢谢, 马库斯
答案 0 :(得分:2)
看起来您的问题与此相同:https://stackoverflow.com/questions/268117/safearray-of-structs
具体来说,请参阅http://vcfaq.mvps.org/com/4.htm:
SafeArrayCreateEx(VT_RECORD)
,SafeArrayAccessData
和SafeArrayUnaccessData
填充数组答案 1 :(得分:1)
COM对结构的支持非常差。您至少需要使用IRecordInfo来发现结构的布局,即SafeArrayCreateEx()的第4个参数。实际上并不确定CLR是否支持此功能。或者如何获取IRecordInfo接口指针。
您的C ++代码否则有正确的想法。不要使用结构,使用[ComVisible]类。结构成员可以只是属性。