droland
droland

Reputation: 19

Passing a c# array of object to COM interface method

I should pass a pointer of object array to a COM interface with the following IDL and C++ definitions: C++ code:

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 generated C# code:

UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In][MarshalAs(UnmanagedType.Struct)] ref object pvValues);

... and I try to call with:

FieldIdEnum[] fieldIDs = { FieldIdEnum.fi1ID, FieldIdEnum.fi2At };
object[] values = { 3, DateTime.UtcNow };
mi.UpdateItem(1, 2, ref fieldIDs[0], ref values[0]);

I get this interface from my system as result of login and authentication process... The UpdateItem method is a public member of that interface.

I want to pass two or more field and value pairs (in same time) by the two array. The field array always is passed correctly to C++ code. I have debugged C++ code and the "FieldIdEnum* pFields" represents the first element of an integer array and the 2nd element (pFields1) is correct too. The pField[] is a c-style array.

But the 2nd array is a variant array with various element type in this case an integer and a date time. This appears as a SafeArray at c++ side instead of c_style array. I have checked this 2nd array too, it is a simple variant array if the method calling starts from another C code, but C# tries to marshal it to safearray.

I have changed the C# definition to

UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In] ref object pvValues);

It does not work I always get an exception like "Value does not fall within the expected range." "System.Exception {System.ArgumentException}"

I have tried to use/marshal various managed/unmanaged types and Intptr, did not work.

I have found an other topic with same/similar problem, I could not make it work.

How should I pass a pointer of object array to COM interface?

Upvotes: 2

Views: 271

Answers (1)

droland
droland

Reputation: 19

I have found the solution. I have redefined the interface method:

        void UpdateItem([In] int lID, [In] int lNumOfFields, [In] ref FieldIdEnum pFields, [In][MarshalAs(UnmanagedType.LPArray)] object[] pvValues);

... and call this as:

            FieldIdEnum[] updateFieldIDs = { FieldIdEnum.fi1ID, FieldIdEnum.fi2At };
            object[] values = { 3, DateTime.UtcNow };
            
            mi.UpdateItem(id, updateFieldIDs.Length, ref updateFieldIDs[0], values);

Thank you for guidance.

Upvotes: -1

Related Questions