将对象的 c# 数组传递给 COM 接口方法
Passing a c# array of object to COM interface method
我应该将对象数组的指针传递给具有以下 IDL 和 C++ 定义的 COM 接口:
C++代码:
UpdateItem( LONG lID, LONG lNumOfFields, FieldIdEnum* pFields, VARIANT* pvValues )
IDL:
HRESULT UpdateItem( [in] LONG lID, [in] LONG lNumOfFields, [in, size_is(lNumOfFields)] FieldIdEnum* pFields, [in, size_is(lNumOfFields)] VARIANT* pvValues );
tlbimp 生成的 C# 代码:
UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In][MarshalAs(UnmanagedType.Struct)] ref object pvValues);
... 我试着打电话给:
FieldIdEnum[] fieldIDs = { FieldIdEnum.fi1ID, FieldIdEnum.fi2At };
object[] values = { 3, DateTime.UtcNow };
mi.UpdateItem(1, 2, ref fieldIDs[0], ref values[0]);
作为登录和身份验证过程的结果,我从我的系统获得了这个界面...UpdateItem 方法是该界面的 public 成员。
我想通过两个数组(同时)传递两个或多个字段和值对。
字段数组始终正确传递给 C++ 代码。我调试了 C++ 代码,“FieldIdEnum* pFields”代表整数数组的第一个元素,第二个元素 (pFields1) 也是正确的。 pField[] 是一个 c 风格的数组。
但是第二个数组是一个具有各种元素类型的变体数组,在本例中是一个整数和一个日期时间。这在 C++ 端显示为 SafeArray 而不是 c_style 数组。我也检查了这个第二个数组,如果方法调用从另一个 C 代码开始,它是一个简单的变体数组,但 C# 试图将它编组到 safearray。
我已将 C# 定义更改为
UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In] ref object pvValues);
它不起作用我总是收到“值不在预期范围内”之类的异常。 “System.Exception {System.ArgumentException}”
我试过 use/marshal 各种 managed/unmanaged 类型和 Intptr,没有用。
我发现 other topic 有 same/similar 问题,我无法让它工作。
如何将对象数组的指针传递给 COM 接口?
我找到了解决办法。
我重新定义了接口方法:
void UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In][MarshalAs(UnmanagedType.LPArray)] object[] pvValues);
...并将其称为:
FieldIdEnum[] updateFieldIDs = { FieldIdEnum.fi1ID, FieldIdEnum.fi2At };
object[] values = { 3, DateTime.UtcNow };
mi.UpdateItem(id, updateFieldIDs.Length, ref updateFieldIDs[0], values);
感谢指导。
我应该将对象数组的指针传递给具有以下 IDL 和 C++ 定义的 COM 接口: C++代码:
UpdateItem( LONG lID, LONG lNumOfFields, FieldIdEnum* pFields, VARIANT* pvValues )
IDL:
HRESULT UpdateItem( [in] LONG lID, [in] LONG lNumOfFields, [in, size_is(lNumOfFields)] FieldIdEnum* pFields, [in, size_is(lNumOfFields)] VARIANT* pvValues );
tlbimp 生成的 C# 代码:
UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In][MarshalAs(UnmanagedType.Struct)] ref object pvValues);
... 我试着打电话给:
FieldIdEnum[] fieldIDs = { FieldIdEnum.fi1ID, FieldIdEnum.fi2At };
object[] values = { 3, DateTime.UtcNow };
mi.UpdateItem(1, 2, ref fieldIDs[0], ref values[0]);
作为登录和身份验证过程的结果,我从我的系统获得了这个界面...UpdateItem 方法是该界面的 public 成员。
我想通过两个数组(同时)传递两个或多个字段和值对。 字段数组始终正确传递给 C++ 代码。我调试了 C++ 代码,“FieldIdEnum* pFields”代表整数数组的第一个元素,第二个元素 (pFields1) 也是正确的。 pField[] 是一个 c 风格的数组。
但是第二个数组是一个具有各种元素类型的变体数组,在本例中是一个整数和一个日期时间。这在 C++ 端显示为 SafeArray 而不是 c_style 数组。我也检查了这个第二个数组,如果方法调用从另一个 C 代码开始,它是一个简单的变体数组,但 C# 试图将它编组到 safearray。
我已将 C# 定义更改为
UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In] ref object pvValues);
它不起作用我总是收到“值不在预期范围内”之类的异常。 “System.Exception {System.ArgumentException}”
我试过 use/marshal 各种 managed/unmanaged 类型和 Intptr,没有用。
我发现 other topic 有 same/similar 问题,我无法让它工作。
如何将对象数组的指针传递给 COM 接口?
我找到了解决办法。 我重新定义了接口方法:
void UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In][MarshalAs(UnmanagedType.LPArray)] object[] pvValues);
...并将其称为:
FieldIdEnum[] updateFieldIDs = { FieldIdEnum.fi1ID, FieldIdEnum.fi2At };
object[] values = { 3, DateTime.UtcNow };
mi.UpdateItem(id, updateFieldIDs.Length, ref updateFieldIDs[0], values);
感谢指导。