I am trying to pass a 2D mask (all 0s, expect for a region of interest as 1s) from C# ( as short[]) to C++ (as unsigned short*), but I cannot get the right value in C++.
C#
[DllImport("StatsManager.dll", EntryPoint = "SetStatsMask")]
private static extern int SetStatsMask(IntPtr mask, int imgWidth, int imgHeight);
short[] mask;
mask = new short[8*8];
// some operation here making a ROI in mask all 1. ex 0000111100000000 in 1D
IntPtr maskPtr = Marshal.AllocHGlobal(2 * mask.Length);
Marshal.Copy(mask, 0, maskPtr, mask.Length);
SetStatsMask(maskPtr, width, height);
C++
long StatsManager::SetStatsMask(unsigned short *mask, long width, long height)
{
//create memory to store the incoming mask
//memcpy the mask to the new buffer
//pMask = realloc(pMask,width*height*sizeof(unsigned short));
long ret = TRUE;
if (NULL == _pMask)
{
_pMask = new unsigned short[width * height];
}
else
{
realloc(_pMask,width*height*sizeof(unsigned short));
}
memcpy(mask,_pMask,width*height*sizeof(unsigned short));
SaveBuffer(_pMask, width, height);
return ret;
}
But all I can see for mask in C++ using watch window is 52536 instead of 0000111100000000, so I am wondering where I messed up? Anyone can help? Thanks.
maskparameter in C# to accept aushort[]-- the array will be marshaled automatically tounsigned short *.IntPtrparameter should be changed toushort[], then just pass your C# array directly. The P/Invoke layer will marshal it to a C-style array for you. You do not need to use any of theMarshalmethods you are using.SetStatsMask(mask, width, height);. (BTW this will not fix your problem, but frees you of the burden to get the array marshal code correct, including freeing your allocation. Let the P/Invoke layer do this for you!)