У меня есть локальный сервер 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
. Это взято из этого вопроса стекопотока . Я использовал это, чтобы написать 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 (с использованием VT_I4
& int
вместо short
в 3 местах).
Оставляя BYTE
в IDL.
Оставляя safearrayData
как BYTE*
Только чтобы получить ту же ошибку. Что может быть решением этого? Можно ли использовать любой другой тип, кроме BYTE
? например INT
?