none
Call Unmanaged DLL with Structures from C# RRS feed

  • Question


  • Hi:
    I am trying to call a function in an unmanaged (C++ 6.0) DLL from my C-Sharp code.  The function has a structure with nested structures as a parameter.
    Here is what the C++ header says:

    struct DPoint
    {
        double x;
        double y;
    };

    struct LPoint
    {
        long x;
        long y;
    };

    struct EyeData
    {
        DPoint Pupil;
        DPoint Glint1;
        DPoint Glint2;
        LPoint GazePoint;
        double PupilDiameter;
        bool   Found;
        bool   Calibrated;
    };

    struct ImageData
    {
        double          Time;
        EyeData         LeftEye;
        EyeData         RightEye;
        unsigned char * PixelData;
        int             Width;
        int             Height;
    };


    bool  GetImageData( unsigned long MaxTimeout,  ImageData * Data);

    Here is my C# Code

        public struct DPoint
          {
          public double x;
          public double y;
          };

        public struct LPoint
          {
          public long x;
          public long y;
          };

        public struct EyeData
          {
          public DPoint Pupil;
          public DPoint Glint1;
          public DPoint Glint2;
          public LPoint GazePoint;
          public double PupilDiameter;
          public bool   Found;
          public bool   Calibrated;
          };

        public struct ImageData
          {
          public double          Time;
          public EyeData LeftEye;
          public EyeData         RightEye;
          public char[] PixelData;
          public int             Width;
          public int             Height;
          };


        [DllImport( "QuickLinkAPI.dll" )]
        public static extern bool GetImageData( long MaxTimeout, ref ImageData Data);

        public bool ET_GetImageData( long MaxTimeout, ref ImageData Data )
          {
          return GetImageData( MaxTimeout, ref Data);
          }



    And here is my call

       ImageData stImage = new ImageData();
       Boolean       bValidImageData = GetImageData(100, ref stImage);

    When I run I get this error:
    An unhandled exception of type 'System.AccessViolationException' occurred in EyeTech-Sharp.exe
    Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

    I think my problem might be with
    public char[] PixelData;
    but I can't find a solution.

    The problem doesn't happen with C++ 6.0 code calling into the DLL.

    Any help would be much appreciated.

    Thanks,
    John
     





    Tuesday, March 10, 2009 6:22 PM

Answers

  • Couple of mistakes.  The 1st argument of the function must be declared as uint, not long.  The PixelData member must be declared as byte[].  And you need to make sure that you allocate Data.PixelData to be the correct size.

    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Monday, March 16, 2009 10:31 AM
    Tuesday, March 10, 2009 7:17 PM
    Moderator
  • You also need to add something like [StructLayout(LayoutKind::Sequential, Pack=8)]  to your struct. Without a sequential layout the managed structure can store members in any order. And you need to make sure the packing alignment matches the packing alignment used in your C++ DLL.
    MSMVP VC++
    • Marked as answer by Zhi-Xin Ye Monday, March 16, 2009 10:31 AM
    Tuesday, March 10, 2009 7:28 PM

All replies

  • Couple of mistakes.  The 1st argument of the function must be declared as uint, not long.  The PixelData member must be declared as byte[].  And you need to make sure that you allocate Data.PixelData to be the correct size.

    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Monday, March 16, 2009 10:31 AM
    Tuesday, March 10, 2009 7:17 PM
    Moderator
  • You also need to add something like [StructLayout(LayoutKind::Sequential, Pack=8)]  to your struct. Without a sequential layout the managed structure can store members in any order. And you need to make sure the packing alignment matches the packing alignment used in your C++ DLL.
    MSMVP VC++
    • Marked as answer by Zhi-Xin Ye Monday, March 16, 2009 10:31 AM
    Tuesday, March 10, 2009 7:28 PM
  • Hi,

    I am also stuck at this point and my coding is below.

     

     public struct ConvertedData 
    {
                public int width;
                public int height;
                [MarshalAs(UnmanagedType.LPArray)]
                public byte[] Buf;      
    };
    
    [DllImport("DataTest.dll", CharSet = CharSet.Auto, EntryPoint = "Converted")]
    public static extern ConvertedData Converted([In, Out][MarshalAs(UnmanagedType.LPArray)]byte[] buf, int size, int type);
    
    ConvertedData  cdata = new ConvertedData();
    
    //here data is system.array
    cdata = Converted(data, size, type);
    

     Please advise me to call structure and unsigned char * calling from C++ DLL to C#.

     

    Thanks

     

     

     

    Tuesday, March 23, 2010 12:15 AM
  • Pinvoke Interop Assistant tool may help you with this.

    http://clrinterop.codeplex.com/releases/view/14120

     

     

    Thursday, March 25, 2010 3:43 PM