none
Unable to pass array of structs from C# to C++ COM dll RRS feed

  • Question

  • Hi,

    I have a C++ COM dll which has a structure defined as given below:

    typedef struct mystruct

    {

    int i;

    long l;

    BSTR str;

    }mystruct;

     

    The above struct is defined in the idl file of the COM Component. I have a function in my idl file which takes an array of the above struct as an input parameter.

    HRESULT func1([in] SAFEARRAY(mystruct) pArr);

    I have created an interop for my dll using 'tlbimp.exe' tool. I am trying to use this Interop dll to access this COM methods in a managed C# application.

    It works fine for a Managed Application built in .Net 3.5.

    The same Interop gives me an error when i call the function from a .Net 4.0 application. (Error : The parameter is incorrect. (Exception from HRESULT: 0x80070057)). I am not doing any custom marshalling for the strings as i get all the structs defined in my COM application in the interop itself.

    I am using Visual Studio 2010 Ultimate SP1 on Windows 2008 SP2 machine.

    Thanks in advance.

    Vamsikrishna Atluri

    • Moved by lucy-liu Tuesday, June 7, 2011 3:09 AM it is related to clr (From:Visual C# General)
    Sunday, June 5, 2011 5:25 AM

Answers

  • Hi Paul,

    Thanks for the reply. Unfortunately, it did not work. Good news is that we got the issue fixed as given below.

    The issue seems to be with the new 'Embed Interop Type' property in .Net 4.0 . In a managed client App built in .Net 4.0, if we add a reference to the Interop.dll, the property 'Embed Interop Type' is set to True which means it embeds all the types needed by the managed assembly. It does not seem to embed all the required structures defined in our case.

    If we set the property 'Embed Interop Type' of the Interop reference as false, the Interop is deployed along with the client and it works fine.

    If we try to generate the interop as suggested, it does not compile in VS 2010 as it says 'out' parameter does not take 'In' attribute.

    'void func1([In, out, MarshalAs(UnmanagedType.SafeArray)] out mystruct[] pArr);

    Thanks & Regards,

    Vamsikrishna Atluri

    Monday, June 13, 2011 6:01 PM

All replies

  • Hi Vamsikrishna,

    I am moving this thread from “Visual C# General" forum to the “Common Language Runtime” forum.

    Since the issue is related to CLR. There are more experts in the “Common Language Runtime" forum.

     And you will get quicker and better responses.

     

    Best regards,

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, June 7, 2011 3:09 AM
  •  

    Hi Vamsikrishna,

     

    Welcome to the MSDN forum.

     

    Could you please provide some code snippet where use the structure in managed code?

    Any more information that helps us to reproduce this issue is appreciated.

     

    Thanks.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, June 8, 2011 8:39 AM
  • Hi Paul,

    Thanks for you reply. As we defined the structure in the idl file, we get the definition of it in the interop. Now, create an instance of the COM class from the interop generated using tlbimp or generated manually. Call the method on the class instance. Please find below the Code snippet I am using in my Managed Code.

    //Create an array of struct
    mystruct[] mArr = new mystruct[3];
    
    //Assign some values to the array before passing it to the unmanaged code.
    classInstance.func1(mArr);
    
    I have generated the interop manually in the following way. Even this way I face an issue with .net 4.0 client.

    //The CTempClass implements the ITempInterface given below in the unmanaged C++ code.
    
    using System.Runtime.InteropServices;
    
    [StructLayout(LayoutKind.Sequential), Serializable]
    struct mystruct
    {
      public int i;
      public int l;
    
      [MarshalAs(UnmanagedType.BStr)]
      public string str;
    
    }mystruct;
    
    [ComImport, Guid("<Class GUID from the IDL file>")]
    public class CTempClass
    {
    }
    
    
    [Guid("<Interface GUID from IDL file>"),
      InterfaceType(ComInterfaceType.InterfaceIsDual)] 
    public interface ITempInterface
    {
      void func1([in, MarshalAs(UnmanagedType.SafeArray)] mystruct[] pArr);
    }
    

    Wednesday, June 8, 2011 10:37 AM
  •  

    Hi Vamsikrishna,

     

    Please follow the trouble-shooting steps below to resolve this issue:

     

    Firstly, we can try to modify the declaration in idl file:

    HRESULT func1([in, out] SAFEARRAY(mystruct) *pArr);

     

    Then, secondly, we generate the interop as below:

    void func1([in, out, MarshalAs(UnmanagedType.SafeArray)] out mystruct[] pArr);

     

    Moreover, Interop assemblies do not replace the COM components they represent; the unmanaged COM functions remain in the COM component, so the component must be installed and registered on target computers or calls to the interop assembly fail.

     

    More information, please refer to:

    UnmanagedType Enumeration


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Paul Zhou Monday, June 13, 2011 6:08 AM
    • Unmarked as answer by Paul Zhou Tuesday, June 14, 2011 1:59 AM
    Thursday, June 9, 2011 7:39 AM
  •  

    Hi Vamsikrishna,

     

    Has your issue been resolved? Would you mind letting us know the result of the suggestions?

     

    Now I will mark an answer, you can mark others that you think to be so useful to your issue.

    If you still have any questions about this issue, please feel free to let me know. We will continue to work with you on this issue.

     

    Have a nice day!


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, June 13, 2011 6:08 AM
  • Hi Paul,

    Thanks for the reply. Unfortunately, it did not work. Good news is that we got the issue fixed as given below.

    The issue seems to be with the new 'Embed Interop Type' property in .Net 4.0 . In a managed client App built in .Net 4.0, if we add a reference to the Interop.dll, the property 'Embed Interop Type' is set to True which means it embeds all the types needed by the managed assembly. It does not seem to embed all the required structures defined in our case.

    If we set the property 'Embed Interop Type' of the Interop reference as false, the Interop is deployed along with the client and it works fine.

    If we try to generate the interop as suggested, it does not compile in VS 2010 as it says 'out' parameter does not take 'In' attribute.

    'void func1([In, out, MarshalAs(UnmanagedType.SafeArray)] out mystruct[] pArr);

    Thanks & Regards,

    Vamsikrishna Atluri

    Monday, June 13, 2011 6:01 PM
  •  

    I'm glad to hear that you got it working.

    Thank you for sharing your solutions & experience here. It will be very beneficial for other community members who have similar questions.

     

    Sincerely,


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, June 14, 2011 2:00 AM