1

I am using the following code to marshal an array of structs to c++:

[DllImport("IPD.dll", EntryPoint = "process", CallingConvention = CallingConvention.Cdecl)]
public static extern Pixel* process(Pixel* pixels, int numPoints, uint processingFactor);    
[StructLayout(LayoutKind.Sequential)]
public unsafe struct Pixel
{
    public fixed byte x[3];
    public uint numebrOfPixels;
}  
...
Pixel[] pixels = extractPixels(image);
fixed (Pixel* ptr = pixels)
{
            Pixel* result = process(ptr, pixels.Length,processingFactor);
}

In order to populate my struct I am using the following code:

//Looping and populating the pixels    
for(i=0;i<numOfPixels;i++)  
{
   fixed (byte* p = pixels[i].x)
   {
                p[0] = r;
                p[1] = g;
                p[2] = b;
   }
}

The code works just fine with no memory leaks.
How can I be sure the during marshaling the pixels to the native code the CLR doesn't copy the pixels array back and forth?

Cheers,
Doron

1
  • Just as a suggestion: if the returned Pixel* are distinct pixels from the one passed as an input parameter, then it is probably better to pass them as an input parameter as a second Pixel* pixelOut, so that C#-side you can have a Pixel[] even for the output pixels. Commented Apr 13, 2015 at 7:59

2 Answers 2

2

The way you can be sure that the marshaller doesn't copy members of the array is that the marshaller doesn't know the size of the array. It is simply not capable of marshalling the array contents. You are simply passing the address of a pinned array. No copying of the content of that array is performed.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! As you can see I am use the fixed buffer and therefor when I am populating the struct pixels array I need to use a fixed scope. This has performance penalty. What is the alternative?
Use a uint in place of that fixed buffer, and form the value with bitwise operations.
0

You can use the In Attribute to specify an argument that needs to be marshaled from the caller to the callee:

[DllImport("IPD.dll", EntryPoint = "process", CallingConvention = CallingConvention.Cdecl)]
public static extern Pixel* process([In] Pixel* pixels, int numPoints, uint processingFactor);

1 Comment

[In] is the default for parameters

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.