none
How to Marshal a structure with variable length arrays from C# to C++ COM dll (and visa versa) RRS feed

  • Question

  • Hi,

    I am having problems marshaling  a structure with variable length arrays from C# to C++ COM dll (and visa versa)

    I have a C++ COM object and I am trying to call a function that takes a structure IntList.

    This is the IntList structure definition in C++. It contains a variable length array.

    typedef struct __IntList

    {

        long             count;

        [size_is(count)] long* values;

    } IntList;

    And this is the function I call

    HRESULT test_intList([in] IntList* ints);

    When I add a reference to the COM object in my C# test program the structure is converted as

        [ComConversionLoss]

        public struct __IntList

        {

            public int count;

            [ComConversionLoss]

            public IntPtr values;

    }

    I am having problems creating the values field of the IntList structure. When it is passed to the COM object the first value in the array is correct but the rest is not.

    Here is one of the ways I tried

            void test_intList()

            {

                __IntList int_list = new __IntList();

                int_list.count = 2;

                Int32[] xx = new Int32[2] {22, 44};

                int_list.values = Marshal.AllocCoTaskMem(int_list.count * Marshal.SizeOf(typeof(Int32)));

                Marshal.Copy(xx, 0, int_list.values, int_list.count);

                COMOBJECT.test_intList(int_list);

            }

    How can I get the values field of the IntList to get correctly passed to the COM object?

    Thanks in advance for your help!!!

    Alex


    A Enterline

    Tuesday, January 9, 2018 4:09 PM

Answers

  • In my quick and dirty test I found that a proxy/stub dll was required in order to correctly marshal the variable sized array between managed C# and unmanaged COM object hosted in a dll. 

    If you change the COM code to use a SAFEARRAY C# would be able to marshal a managed array to the COM dll without a separate proxy/stub dll.  And SAFEARRAY could accomodate the need for variable sizes.


    • Edited by RLWA32 Wednesday, January 10, 2018 12:00 PM
    • Marked as answer by MyDisplayNameAlex Wednesday, January 10, 2018 8:21 PM
    Wednesday, January 10, 2018 11:59 AM

All replies

  • Did you remember to register the proxy/stub dll for the COM object?
    • Proposed as answer by RLWA32 Wednesday, January 10, 2018 8:04 PM
    Tuesday, January 9, 2018 9:50 PM
  • Hi,

    Thanks for your quick response!  Ours in an in-process COM (a dll) and we do not use a proxy/stub dll.  Our COM component generates a type library which handles the marshaling.  This is an old COM component that we have updated over the years. It has many structures in the IDL that we use to pass data to and from the COM.  We have arrays in structures, and structures nested within structures which works fine as long as all arrays have their length hardwired in the structures (for example "float myval[50]"). We would prefer to dynamically declare/allocate the length of certain arrays because it is safer, i.e. we may find in 5 years that "myval" needs to be dimensioned at 60 instead of 50 and now we are stuck!.

    Thanks for your help,

    Alex


    A Enterline

    Wednesday, January 10, 2018 11:44 AM
  • In my quick and dirty test I found that a proxy/stub dll was required in order to correctly marshal the variable sized array between managed C# and unmanaged COM object hosted in a dll. 

    If you change the COM code to use a SAFEARRAY C# would be able to marshal a managed array to the COM dll without a separate proxy/stub dll.  And SAFEARRAY could accomodate the need for variable sizes.


    • Edited by RLWA32 Wednesday, January 10, 2018 12:00 PM
    • Marked as answer by MyDisplayNameAlex Wednesday, January 10, 2018 8:21 PM
    Wednesday, January 10, 2018 11:59 AM
  • Hi,

    Thank you for your very quick response.  We will try the SAFEARRAY today!

    Alex


    A Enterline

    Wednesday, January 10, 2018 12:05 PM
  • Hi,

    We now use a proxy/stub for marshaling and our data passes to the COM perfectly. 

    Thank you, thank you!!

    Alex


    A Enterline

    Wednesday, January 10, 2018 7:55 PM
  • Hi,

    We now use a proxy/stub for marshaling and our data passes to the COM perfectly. 

    Thank you, thank you!!

    Alex


    A Enterline

    Thanks for the follow-up.  I'd appreciate it if you would consider marking my initial response as an answer.
    Wednesday, January 10, 2018 8:03 PM
  • Thank you for the courtesy.
    Wednesday, January 10, 2018 8:28 PM