none
Marshalling 2 dimensional arrays from COM RRS feed

  • Question

  • Hi

    I have a COM component which pushes a 2 dimensional double array to a client.

    The IDL is:

     

    interface IMyClient : IUnknown
    {
      [helpstring("method CollectData")] HRESULT CollectData([in] long channel_count,
                                    [in] long data_count,
                                    [in, size_is(channel_count)] long* pChannels,
                                    [in, size_is(channel_count, data_count)] double** pData);
    
    }
    
     In C# the method is implemented as

    public void CollectData(int channel_count, int data_count, ref int pChannels, IntPtr pData)
    
    Does anyone know how I can read the pData values passed up from the COM component as doubles?

    Thank you for any help.

    Bob

     

    Tuesday, November 16, 2010 11:23 AM

Answers

  • This is a start:

    public void CollectData(
     [In] int channel_count,
     [In] int data_count,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] pChannels,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] pData);
    

    But still you must use Marshal.Copy(IntPtr, double[], int, int) to read each arrays of doubles. OTOH, this cannot work:

    public void CollectData(
     [In] int channel_count,
     [In] int data_count,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] pChannels,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, ArraySubType = UnmanagedType.LPArray)] double[][] pData);
    

    b/c there is no way to give the subarrays sizes. (no such thing as "SubSizeParamIndex = 1")

    • Marked as answer by Mikesfsfgsfg Wednesday, November 17, 2010 2:26 PM
    Tuesday, November 16, 2010 11:49 PM

All replies

  • This is a start:

    public void CollectData(
     [In] int channel_count,
     [In] int data_count,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] pChannels,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] pData);
    

    But still you must use Marshal.Copy(IntPtr, double[], int, int) to read each arrays of doubles. OTOH, this cannot work:

    public void CollectData(
     [In] int channel_count,
     [In] int data_count,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] pChannels,
     [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, ArraySubType = UnmanagedType.LPArray)] double[][] pData);
    

    b/c there is no way to give the subarrays sizes. (no such thing as "SubSizeParamIndex = 1")

    • Marked as answer by Mikesfsfgsfg Wednesday, November 17, 2010 2:26 PM
    Tuesday, November 16, 2010 11:49 PM
  • Thanks for the help.

    I used

     

    public
    
    
     void
     CollectData(int
     channel_count, int
     data_count, 
    [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ref int pChannels, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr pData)
    and then used the marshalJaggedFromC method in a previous answer .

     

    Wednesday, November 17, 2010 2:29 PM