我有一个C ++ COM本地服务器和C#客户端。我有两种使用SAFEARRAY
将数据从服务器传递到客户端的事件方法:
// defenition in IDL file
HRESULT Foo1([in] SAFEARRAY(BYTE) param);
HRESULT Foo2([in] SAFEARRAY(short) param);
// as generated in the _i.h file
virtual HRESULT STDMETHODCALLTYPE Foo1(/*[in]*/ SAFEARRAY* param) = 0;
virtual HRESULT STDMETHODCALLTYPE Foo2(/*[in]*/ SAFEARRAY* param) = 0;
// actual use
SAFEARRAY *data1;
PackBytes(byteLen, byteData, &data1);
IMyEvent->Foo1(data1);
SAFEARRAY *data2;
PackBytesShort(shortLen, shortData, &data2);
IMyEvent->Foo2(data2);
PackBytes
将BYTE
数组转换为SAFEARRAY
。它取自this stackoverflow question。我用它来写PackBytesShort
,所以(总共进行了4次更改):
HRESULT PackBytesShort(ULONG count, const short* pData, /*[ref]*/ LPSAFEARRAY* pResult)
{
// initialize output parameters
*pResult = NULL;
// describe the boundaries of the safearray (1 dimension of the specified length, starting at index 0)
SAFEARRAYBOUND bound{ count, 0 }; // bugfix: 1 changed to 0
// create the safearray
LPSAFEARRAY safearray = SafeArrayCreate(VT_I2, 1, &bound);
if (!safearray)
return E_OUTOFMEMORY;
// when there is actually data...
if (count > 0)
{
// begin accessing the safearray data
short* safearrayData;
HRESULT hr = SafeArrayAccessData(safearray, reinterpret_cast<LPVOID*>(&safearrayData));
if (FAILED(hr))
{
SafeArrayDestroy(safearray);
return hr;
}
// copy the data into the safearray
memcpy(safearrayData, pData, count*sizeof(short));
// finish accessing the safearray data
hr = SafeArrayUnaccessData(safearray);
if (FAILED(hr))
{
SafeArrayDestroy(safearray);
return hr;
}
}
// set output parameters
*pResult = safearray;
// success
return S_OK;
}
客户端代码签名:
public void Foo1(Array param);
public void Foo2(Array param);
调用Foo1
成功,并且到达客户端代码。 Foo2
失败,并出现SafeArrayTypeMismatchException:“ 数组的运行时类型与元数据中记录的子类型之间发生不匹配”。永远不会到达客户端代码。
我尝试过:
从short
变为int
:在IDL中,在PackBytesShort中(在3个地方使用VT_I4
和int
代替short
)。
将BYTE
留在IDL中。
将safearrayData
保留为BYTE*
仅出现相同的错误。有什么解决方案?是否可以使用BYTE
以外的其他类型?例如INT
?