Как маршалировать структурный массив с помощью intptr.
У меня есть следующий код в библиотеке DLL C++
typedef struct _MYPOINT { int nX; int nY; } MYPOINT; extern "C" __declspec(dllexport) void ModifyPointArray (int nSize, MYPOINT *ptArr[]) { for ( int nI = 0; nI < nSize; nI++ ) { ptArr[nI]->nX +=5; ptArr[nI]->nY +=5; } }
======================================
Я определил класс-оболочку для DLL примерно так.
namespace MarshalDemo { [StructLayout(LayoutKind.Sequential)] public class MyPoint { public int nX; public int nY; public MyPoint() { this.nX = 0; this.nY = 0; } public MyPoint(int x, int y) { this.nX = x; this.nY = y; } } public static class MarshalDllWrapper { [DllImport("MarshalDll.dll")] public static extern void ModifyPointArray(int nSize, IntPtr [] arrPts); } }
Что я уже пробовал:
Теперь я пытаюсь вызвать эту функцию с помощью маршалинга с помощью IntPtr, мой клиентский код .NET (C#) выглядит примерно так.
MyPoint[] pointArr = { new MyPoint(5, 6), new MyPoint(7, 8), new MyPoint(9, 10) }; int nCount = pointArr.Length; IntPtr[] ptrArr = new IntPtr[nCount]; for (int nI=0; nI< nCount; nI++) { ptrArr[nI] = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(MyPoint))); Marshal.StructureToPtr(pointArr[nI], ptrArr[nI], true); } MarshalDllWrapper.DisplayPointArray(nCount, ptrArr); MyPoint[] pointArr2 = new MyPoint[nCount]; for (int nI = 0; nI < nCount; nI++) { Marshal.PtrToStructure(ptrArr[nI], pointArr2[nI]); Marshal.FreeCoTaskMem(ptrArr[nI]); }
Я получаю ошибку на линии
//F:\VS2010\VCS2010\Marshalling\MarshalDll\MarshalDllClient\frmMarshalDemo.cs:line ХХХ
Marshal.PtrToStructure(ptrArr[nI], pointArr2[nI]);
с сообщением об ошибке
Система.ArgumentNullException: значение не может быть null.
Имя параметра: структура
в System.Runtime.InteropServices.Маршал.PtrToStructureHelper(IntPtr ptr, Object structure, Boolean allowValueClasses)
в System.Runtime.InteropServices.Маршал.PtrToStructure(IntPtr ptr, структура объекта)
в MarshalDemo.frmMarshalDemo.btnPointArray_Click(отправитель объекта, EventArgs e) в F:\VS2010\VCS2010\Marshalling\MarshalDll\MarshalDllClient\frmMarshalDemo.cs:line 150
PS : Я знаю, если я напишу обертку что-то вроде этого.
public static extern void ModifyPointStructArray(int nSize, [In, Out] MyPoint[] arrstruct);
это работает как ветер, но я хочу сделать с IntPtr, я делаю что-то концептуально неправильное ?
Что я делаю не так ?
Любая помощь будет оценена по достоинству.
Спасибо.
Правин.