[RESOLVED] Marshal C struct containing pointer to other C struct
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: [RESOLVED] Marshal C struct containing pointer to other C struct

  1. #1
    Join Date
    May 2002
    Posts
    487

    [RESOLVED] Marshal C struct containing pointer to other C struct

    I have a DLL written in C that I must use in my C# application.

    The C declarations for the two functions in question are as follows:

    Code:
    IMGSTRUCT *LoadImg(const char *filename)
    int UseImg(IMGSTRUCT *img,int flag)
    
    The structures are defined as follows in C.
    
    typedef struct tagBITMAPINFOHEADER{
            DWORD      biSize;
            LONG       biWidth;
            LONG       biHeight;
            WORD       biPlanes;
            WORD       biBitCount;
            DWORD      biCompression;
            DWORD      biSizeImage;
            LONG       biXPelsPerMeter;
            LONG       biYPelsPerMeter;
            DWORD      biClrUsed;
            DWORD      biClrImportant;
    } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
    
    typedef struct  {
      LPBITMAPINFOHEADER bi;  // bitmap info
      unsigned char * imgBits;   // image content  
    }
    IMGSTRUCT;
    I know how to marshal the BITMAPINFOHEADER structure.

    Code:
            [StructLayout(LayoutKind.Sequential)]
            public struct BITMAPINFOHEADER
            {
                public uint biSize;
                public int biWidth;
                public int biHeight;
                public ushort biPlanes;
                public ushort biBitCount;
                public uint biCompression;
                public uint biSizeImage;
                public int biXPelsPerMeter;
                public int biYPelsPerMeter;
                public uint biClrUsed;
                public uint biClrImportant;
    
                public void Init()
                {
                    biSize = (uint)Marshal.SizeOf(this);
                }
            }
    How do I marshal the IMGSTRUCT structure?

    It has a member of BITMAPINFOHEADER pointer and a pointer to an array of image data.

    Then how would the P/Invoke look for both LoadImg() and UseImg()?

  2. #2
    Join Date
    Oct 2013
    Posts
    16

    Re: Marshal C struct containing pointer to other C struct

    Can you explain better(with c# examples) how you would like to use them?

    Anyway for the second struct this work?
    Code:
    [StructLayout(LayoutKind.Sequential)]
            public struct IMGSTRUCT
            {
                public BITMAPINFOHEADER bi;
                [MarshalAs(UnmanagedType.ByValArray,SizeConst=1024)]
                public byte[] imgBits; //you should convert a bitmap to byte[] with Marshal.Copy()
            }
    Last edited by Reroto; October 23rd, 2013 at 11:58 AM.

  3. #3
    Join Date
    May 2002
    Posts
    487

    Re: Marshal C struct containing pointer to other C struct

    I first tried these P/Invokes

    Code:
            [DllImport("thirdpartydll.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr LoadImg([MarshalAs(UnmanagedType.LPStr)] string FileName);
    
            [DllImport("thirdpartydll.dll", CharSet = CharSet.Auto)]
            public static extern int UseImg([In] IntPtr Img, int flag);
    
            public delegate void outputDelegate (int infotype, int param);
            [DllImport("thirdpartydll.dll", CharSet = CharSet.Auto)]
            public static extern int SetOutputDelegate(outputDelegate delegate);
    Then I called them from C# like this. The delegate is never getting called.

    Code:
            private outputDelegate _OutputDelegate = new outputDelegate(imgOutputDelegate);
    
            private void startToolStripMenuItem_Click(object sender, EventArgs e)
            {
                int ret = OCRSetOutputHandler(_OCROutputHandler);
    
                // _imgPath previously set
                if (String.IsNullOrEmpty(_imgPath) == false)
                {
                    // single-page TIFF
                    IntPtr imageindex = LoadImg(_imgPath);
    
                    int iRes = UseImg(imageindex, 0);
                }
             }
    
            // delegate that receives events from UseImg()
            private static void imgOutputDelegate(int infotype, int param)
            {
                LogMsg("Inside imgOutputDelegate");
                string test = String.Empty;
    
                // additional processing
            }
    I am thinking the structure is not get marshalled correctly.

    Your sample for the IMGSTRUCT won't work I think because the first member is a pointer to that structure, not the structure itself. The second member is unfortunately a pointer to a variable length array.

    Any thoughts would be appreciated.
    Last edited by Tron; October 23rd, 2013 at 12:56 PM.

  4. #4
    Join Date
    May 2002
    Posts
    487

    Re: Marshal C struct containing pointer to other C struct

    Code:
            [DllImport("thirdpartydll.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr LoadImg([MarshalAs(UnmanagedType.LPStr)] string FileName);
    
            [DllImport("thirdpartydll.dll", CharSet = CharSet.Auto)]
            public static extern int UseImg([In] IntPtr Img, int flag);
    
            public delegate void outputDelegate (int infotype, int param);
            [DllImport("thirdpartydll.dll", CharSet = CharSet.Auto)]
            public static extern int SetOutputDelegate(outputDelegate delegate);
    Well I received a new copy of the thirdpartydll.dll and the above P/Invokes actually do work so I no longer need to attempt to marshal the IMGSTRUCT structure.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center