How can I pass in a pointer to a pointer of a UInt16 array to a Marshalled function?

孤街浪徒 提交于 2019-12-14 02:32:10

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/17746580/how-can-i-pass-in-a-pointer-to-a-pointer-of-a-uint16-array-to-a-marshalled-funct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!