0

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.

7
  • You'd be better off declaring the mask parameter in C# to accept a ushort[] -- the array will be marshaled automatically to unsigned short *. Commented Sep 8, 2014 at 22:12
  • You mean the mask should be declared as ushort[] ? Commented Sep 8, 2014 at 22:14
  • Both the array you are using, and the IntPtr parameter should be changed to ushort[], 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 the Marshal methods you are using. Commented Sep 8, 2014 at 22:15
  • You mean no marshal.Copy() needed? Commented Sep 8, 2014 at 22:19
  • Correct, nor AllocHGlobal(). Just pass in the array directly. 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!) Commented Sep 8, 2014 at 22:20

1 Answer 1

2

I believe you misplaced the parameters of memcpy:

memcpy(mask,_pMask,width*height*sizeof(unsigned short));

As I understand you want to copy from mask to _pMask, so you should write:

memcpy(_pMask, mask, width*height*sizeof(unsigned short));
Sign up to request clarification or add additional context in comments.

1 Comment

Ha, how can I miss that! Thank you, you are awesome!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.