10

You have a structure that takes a byte array

byte[]

however, the size of that array depends on the image you are submitting (widthxheight)

So... how do you do

[MarshalAs(UnmanagedType.ByValArray, SizeConst = ???)]
public Byte[] ImageData;

Is the sizeconst a MUST HAVE when working with byte arrays being passed from C# to C dlls?

1
  • A custom marshaller seems like the only choice. Commented Feb 10, 2017 at 12:50

1 Answer 1

4

You need to change the marshalling type. SizeConst is required if you're marshalling as ByValArray, but not with other types. For details, look at the UnmanagedType enum.

My suspicion is that you want to marshall as a C pointer to the array:

[MarshalAs(UnmanagedType.LPArray)]

This will cause it to marshall through to a standard C array (BYTE*), so only a pointer is passed through. Doing this allows you to pass any sized array. Typically, you'll also want to pass through the array size as another parameter (or image width/height/bpp, which provides the same info), since there's no way in C/C++ to tell that easily.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the reply Reed. However, I did that and now get this error Invalid managed/unmanaged type combination (Arrays fields must be paired with ByValArray or SafeArray) When building the IntPtr and then Marshal.StructureToPtr... Thoughts?
Check out the enum. There would be more information required. I was assuming you were marshalling from managed -> unmanaged, but if you're going the other way around, you can either Marhsal it as an IntPtr (instead of a byte[]) or set it up to use a SafeArray.
Unfortunately using anything but [MarshalAs(UnmanagedType.ArrayByVal, sizeConst = xxxx)] messes up the memory addressing. So essentially there's a struct (which contains a byte[]) that needs to be converted to an IntPtr so it can be passed to the DLL. And the data in the byte[] is getting messed up. Verified this by copying the data from the IntPtr to a byte[] and looking at the data to find that everything is changed unless I've set the MarshalAs in the struct.
@Olewolfe same thing is happening to me with a double array. I am using PInvoke from managed to unmanaged. My double array is also inside a struct. According to MSDN, One-dimensional arrays of blittable types, [are themselves blittable]. However, a type that contains a variable array of blittable types is not itself blittable. I think what this means is that your byte array itself is considered blittable but as soon as you put the array in a struct, the struct looses its blittable-ness.
According to this article the way to get around this is to use a SAFEARRAY.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.