SafeArrayTypeMismatchException

时间:2019-03-29 14:13:30

标签: com interop

我有一个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);

PackBytesBYTE数组转换为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_I4int代替short)。

BYTE留在IDL中。

safearrayData保留为BYTE*

仅出现相同的错误。有什么解决方案?是否可以使用BYTE以外的其他类型?例如INT

0 个答案:

没有答案