我正在尝试将一个UINT32
数组从C#客户端传递给C ++ ATL COM服务。
IDL
声明是:
[propput, id(1)] HRESULT ThingyData([in] SAFEARRAY(UINT32) newVal);
调用它的C#代码是:
thingy.ThingyData = new UInt32[] { (UInt32)1 }.ToArray();
C ++实现是:
STDMETHODIMP CThingy::put_ThingyData(SAFEARRAY * newVal)
{
CComSafeArray<UINT32> sa;
sa.CopyFrom(newVal); //fails here
//... do some other stuff ...
return S_OK;
}
代码在sa.CopyFrom(...)
失败,返回E_INVALIDARG
。我调试了CopyFrom
函数:
HRESULT CopyFrom(_In_ const SAFEARRAY *psaSrc)
{
ATLENSURE_THROW(psaSrc != NULL, E_INVALIDARG);
VARTYPE vt;
HRESULT hRes = ::ATL::AtlSafeArrayGetActualVartype(const_cast<LPSAFEARRAY>(psaSrc), &vt);
ATLENSURE_SUCCEEDED(hRes);
ATLENSURE_THROW(vt == GetType(), E_INVALIDARG);
// ...
}
第二个ATLENSURE_THROW
失败,因为vt == 23 (VT_UINT)
和GetType()
返回19 (VT_UI4)
。
我的代码以32位运行,所以这不应该是一个问题。经过多次挖掘后,我发现我可以明确声明CComSafeArray
使用VT_UINT
:
CComSafeArray<UINT32, VT_UINT> sa;
这令人惊讶。但我不确定这是否是正确的方法。是否存在可移植性或其他奇怪副作用的问题?我想我不建议在COM中使用VT_UINT
读某处。我更喜欢的是让C#以VT_UI4
类型发送数组的方法;那可能吗?
非常感谢。试图围绕所有这些COM的东西。