SafeArrayTypeMismatchException - PullRequest
       12

SafeArrayTypeMismatchException

0 голосов
/ 29 марта 2019

У меня есть локальный сервер 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?

...