I have a following code in a C++ DLL
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;
}
}
======================================
I have defined a Wrapper Class for the DLL something like this.
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);
}
}
What I have tried:
Now i am trying to call this function using Marshalling using IntPtr, my .NET client code (C#) is something like this.
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]);
}
I am getting an Error on line
//F:\VS2010\VCS2010\Marshalling\MarshalDll\MarshalDllClient\frmMarshalDemo.cs:line XXX
Marshal.PtrToStructure(ptrArr[nI], pointArr2[nI]);
with Error Message
System.ArgumentNullException: Value cannot be null.
Parameter name: structure
at System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr ptr, Object structure, Boolean allowValueClasses)
at System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr ptr, Object structure)
at MarshalDemo.frmMarshalDemo.btnPointArray_Click(Object sender, EventArgs e) in F:\VS2010\VCS2010\Marshalling\MarshalDll\MarshalDllClient\frmMarshalDemo.cs:line 150
PS : I know if i write a Wrapper something like this.
public static extern void ModifyPointStructArray(int nSize, [In, Out] MyPoint[] arrStruc);
it works like a breeze, but i want to do with IntPtr, am i doing something conceptually wrong ?
What I am doing wrong ?
Any Help will will apreciated.
Thanks.
Praveen.