7

I'm trying to call the following C++ function that's wrapped up into a DLL:

unsigned char * rectifyImage(unsigned char *pimg, int rows, int cols)

My import statement looks like the following:

[DllImport("mex_rectify_image.dll")]
unsafe public static extern IntPtr rectifyImage(
byte[] data, int rows, int columns);

And my call routine looks like the following:

byte[] imageData = new byte[img.Height * img.Width * 3];
// ... populate imageData
IntPtr rectifiedImagePtr = rectifyImage(imageData, img.Height, img.Width);
Byte[] rectifiedImage = new Byte[img.Width * img.Height * 3];
Marshal.Copy(rectifiedImagePtr, rectifiedImage, 0, 3 * img.Width * img.Height);

However, I keep getting a runtime error:

A first chance exception of type System.AccessViolationException occurred in xxx.dll Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I'm just wondering if the fault lies in the way I'm marshaling my data or in my imported DLL file... anyone have any ideas?

FabianCook
  • 20,269
  • 16
  • 67
  • 115
Tim
  • 71
  • 1
  • 1
  • 2
  • You might wanna have a look at this question: http://stackoverflow.com/questions/289076/how-can-i-pass-a-pointer-to-an-array-using-p-invoke-in-c – Bobby Aug 06 '10 at 18:11
  • 1
    Is the return value from `rectifyImage` supposed to be freed, and if so, how? – Stephen Cleary Aug 06 '10 at 18:25
  • The return value for rectifyImage is used to create a C# Bitmap object, and then freed. I haven't gotten around to trying to figure out how to actually free it yet. – Tim Aug 06 '10 at 18:29

3 Answers3

2

This is likely occurring because the calling convention of the method is not as the marshaller is guessing it to be. You can specify the convention in the DllImport attribute.

You don't need the 'unsafe' keyword in the C# declaration here as it's not 'unsafe' code. Perhaps you were trying it with a 'fixed' pointer at one point and forgot to remove the unsafe keyword before posting?

Tergiver
  • 14,171
  • 3
  • 41
  • 68
1

not sure if this is your problem, but in general C++ pointers map to IntPtr. so try modifying your import statement to this:

[DllImport("mex_rectify_image.dll")]
unsafe public static extern IntPtr rectifyImage(
IntPtr pData, int rows, int columns);
morishuz
  • 2,302
  • 4
  • 21
  • 21
  • not sure why i am getting voted down, but i took the time to answer this so i'd at least expect a comment on why my answer is not to your liking! have you actually tried my suggestion and it didnt work? – morishuz Apr 19 '13 at 20:13
0

rectifyImage Is looking for a ponter to a the 1st byte in a block for data you are sending in the block. Try imageData[0]

binhex213
  • 21
  • 2
  • That's not going to work, since the marshaller would pass a copy of the first byte, rather than its reference. So you'd have to use unsafe code to do that, and pass `&imageData[0]` rather than just `imageData[0]`. – Luaan May 07 '14 at 07:35