C# 填充从C传递的数组时出现了类型不匹配错误#
我试图把一个数组从U.Client传递到C++的ATL COM服务。C# 填充从C传递的数组时出现了类型不匹配错误#,c#,c++,windows,com,safearray,C#,C++,Windows,Com,Safearray,我试图把一个数组从U.Client传递到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)
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;
}
它在第二次抛出时失败,因为vt==23(vt\u UINT)
和GetType()
返回19(vt\u UI4)
我的代码是以32位运行的,所以这应该不是一个真正的问题。在进一步挖掘之后,我发现我可以显式地声明CComSafeArray
以使用VT\u UINT
:
CComSafeArray<UINT32, VT_UINT> sa;
ccomsa;
令人惊讶的是,这是有效的。但我不确定这是否是正确的方式。是否会出现便携性问题,或其他奇怪的副作用?我想我不推荐在COM中使用VT\u UINT
阅读某个地方。我更喜欢的方法是让C#发送带有VT_UI4
类型的数组;可能吗
非常感谢。试着把我的脑袋绕在这些COM的东西上。很难想象你怎么能从CLR中得到一个VT单元。我可以从CLR源代码中反向工程的唯一可行方案是,它是作为UIntPtr[]数组启动的。代码段中的ToArray()也很奇怪,我怀疑实际代码与此非常不同。否则请记住,在互操作代码中使用未签名类型是不寻常的,有许多运行时环境无法使用COM服务器。@HansPassant不,我的代码是这样写的。它不是一个
UIntPtr
数组。我发现,如果我把IDL和C++签名改为<代码> SAFEARE(ULUN)而不是<代码> SAFEARE(UIT32),它工作得很好,C通过了<代码> VTYUI4< /CudioSaveRay.区别是什么有点让人困惑,有什么想法吗?谢谢
CComSafeArray<UINT32, VT_UINT> sa;