-
October 22nd, 2013, 08:58 PM
#1
[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()?
-
October 23rd, 2013, 10:49 AM
#2
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 10:58 AM.
-
October 23rd, 2013, 11:52 AM
#3
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 11:56 AM.
-
October 23rd, 2013, 03:52 PM
#4
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|