Question

I'm attempting to send a pointer to a pointer of a UInt16 array to a marshalled function like so in C#:

C++:

int foo(Unsigned_16_Type** Buffer_Pointer);

C#:

[DllImport("example.dll")]
public static extern int foo(IntPtr Buffer_Pointer);

UInt16[] bufferArray = new UInt16[32];

IntPtr p_Buffer = (IntPtr)Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(UInt16)) * bufferArray.Length);
Marshal.Copy(bufferArray, 0, p_Buffer, bufferArray.Length);  //Issue is here

GCHandle handle = GCHandle.Alloc(p_Buffer, GCHandleType.Pinned);
IntPtr ppUnmanagedBuffer = (IntPtr)handle.AddrOfPinnedObject();

UInt16 word_count = 0;

this.lstbox_DATA_WORDS.Items.Clear();

if ( foo(ppUnmanagedBuffer );

My main problem is with the Marshal.Copy, for the first argument which is the source array, it does not take a UInt16[]. I was wondering if anyone knew how to use Marshal.Copy with a UInt16 array.

Was it helpful?

Solution

There is no Marshal.Copy overload that takes an unsigned short array. Fortunately, ushort and short are the same size, so you can use the Marshal.Copy(Int16[], IntPtr, int) overload. You just need to coerce your ushort[] into a short[] first.

Probably the fastest way to do this is to use Buffer.BlockCopy. It copies bytes, so you just have to tell it to copy 2 bytes per entry:

short[] temp = new short[bufferArray.Length];
System.Buffer.BlockCopy(bufferArray, 0, temp, 0, temp.Length * 2);

This will copy the unsigned 16-bit integer values into a signed 16-bit integer array, but the underlying byte values will remain the same, and the unmanaged code won't know the difference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top