Search code examples
c#c++marshalling

When marshalling a class from c# to native c++ does it clone?


If I have c# code like

[DllImport("SomeDll")]
private static extern void passAClass(ClassType myClass);

and call it like

ClassType myClass = new ClassType();
passAClass(myClass);

I can see that the class (its data segment) is passed to the dll as a pointer, but I am not certain if the runtime copies the class data from its location into new memory and then passes a pointer to that new memory, or if it passes a pointer to the memory location of the class directly.

I can see that if the dll changes data in the memory, it receives a pointer to, that changes is visible in c# after the call, but that could be because it does yet another copy of memory back into where the managed class is stored.


Solution

  • but that could be because it does yet another copy of memory back

    No, that is not automatic, you explicitly have to give the argument the [Out] attribute to ensure that it copies back. The fact that you do see the changes back without the attribute proves that the class is blittable. In other words, the class' fields are all of a simple value type and they did not get re-arranged by the CLR. So the managed layout is identical to the unmanaged layout, allowing the pinvoke marshaller to pin the object and pass a pointer.

    It is not unusual. Best not to make it an accident, you might lose a day of your life some rainy day when you port the native code to x64 for example. Giving the class the [StructLayout] attribute to ensure sequential layout is a good idea.