如何通过C#动态类型从COM服务器获取SAFEARRAY(short)输出参数
问题:动态调用COM服务器的
getData方法时输出数组参数传递错误 我正在使用一个COM服务器,它包含以下两个方法签名:
HRESULT setData ( [in] long id, [in] SAFEARRAY(short) *arr, [in] double* scalar1, [in] double* scalar2 ); HRESULT getData ( [in] long id, [out] SAFEARRAY(short) *arr, [out] double* scalar1, [out] double* scalar2 );
我通过C#动态类型调用这些函数:
Type comType = Type.GetTypeFromProgID("<progid>"); dynamic comObject = Activator.CreateInstance(comType);
其中setData方法可以正常调用:
comObject.setData(new short[] { 0, 0, 1, 2, 3, 4 }, 1.0, 2.0);
但调用getData方法时:
short[] arr = null; comObject.getData(id, out arr, out double scalar1, out double scalar2);
出现错误:
Could not convert argument 2 for call to getData
我还尝试过Array、object等不同类型的参数,但均出现相同错误。请问如何正确传递该输出数组参数?
解决方案
1. 使用object类型接收输出数组
COM的SAFEARRAY在动态调用场景下,无法直接通过强类型数组作为out参数传递,需先用object变量接收结果,再转换为short[]:
long id = 1; // 替换为实际业务ID object arrObj = null; double scalar1, scalar2; comObject.getData(id, out arrObj, out scalar1, out scalar2); short[] arr = (short[])arrObj;
2. 严格匹配参数顺序
注意COM方法签名中getData的第一个参数是必填的[in] long id,调用时必须传入有效值,不能省略(你之前调用setData时省略id能成功,大概率是该方法允许id作为可选参数,但getData不支持)。
3. 反射调用(备选方案)
如果动态类型调用仍有问题,可直接用反射InvokeMember精准控制参数:
long id = 1; object[] paramsArray = new object[] { id, null, null, null }; comType.InvokeMember( "getData", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, comObject, paramsArray ); short[] arr = (short[])paramsArray[1]; double scalar1 = (double)paramsArray[2]; double scalar2 = (double)paramsArray[3];
调用完成后,paramsArray的第2、3、4位会被COM服务器填充返回值。
内容的提问来源于stack exchange,提问作者MiB_Coder
相关产品推荐
相关产品推荐

