首页 > 解决方案 > SafeArrayTypeMismatchException

问题描述

我有一个 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. 它取自这个 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 失败:“数组的运行时类型与元数据中记录的子类型之间发生不匹配”。永远无法到达客户端代码。

我努力了:

从更改shortint:在 IDL 中,在 PackBytesShort 中(在 3 个地方使用VT_I4&int而不是short)。

离开BYTEIDL。

离开safearrayDataBYTE*

只是得到同样的错误。有什么办法可以解决这个问题?可以使用任何其他类型BYTE吗?例如INT

标签: cominterop

解决方案


推荐阅读