Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marshalling array of structs from .NET to C++: when does it do copying?

Consider a struct like System.Drawing.Point - one with LayoutKind.Sequential and containing only primitive members. I have a C# array of such structs.

I'm passing it to an (unmanaged) C++ function via P/Invoke. On the C++ side there's a corresponding definition of the struct (e.g. struct Point { int x, y; };). The function takes a Point* arg.

My question is, in what cases does the CLR copy the data and in what cases does it just pin it? Variables include:

  • Array type: one-dimensional or rectangular
  • C# definition of the function - using Point* or Point[] / Point[,]
  • using fixed(Point* pointer = array) or not

I want to avoid the copying because it's slow.

like image 248
Stefan Monov Avatar asked Dec 16 '11 03:12

Stefan Monov


1 Answers

I don't have much experience with pinning, but, according to my reading of MSDN, your structs should be pinned and not copied. Relevant refs:

  1. Marshalling data with PInvoke
  2. Copying and pinning
  3. Blittable and non-blittable types
  4. Default marshalling for value types

From #2:

Formatted blittable classes have fixed layout (formatted) and common data representation in both managed and unmanaged memory. When these types require marshaling, a pointer to the object in the heap is passed to the callee directly.

And your Point struct is given as an example in #3, so it qualifies as a blittable type.

I noticed some overhead to pinning objects here, but that was for a fixed byte[], which may be different to your Point[].

like image 176
ligos Avatar answered Oct 09 '22 01:10

ligos