views:

164

answers:

2

My gut reaction is no, because managed and unmanaged memory are distinct, but I'm not sure if the .NET Framework is doing something with Marshaling behind the scenes.

What I believe happens is: When getting a struct from my unmanaged DLL, it is the same as making that call gets an IntPtr and then uses it and the Marshal class to copy the struct into managed memory (and changes made to the struct in managed memory do not bubble up).

I can't seem to find this documented anywhere on MSDN. Any links would be appreciated.

Here is what my code looks like:

[DllImport("mydll.dll", BestFitMapping=false, CharSet=CharSet.Ansi)]
private static extern int GetStruct(ref MyStruct s);

[StructLayout(LayoutKind.Sequential, Pack=0)]
struct MyStruct
{
     public int    Field1;
     public IntPtr Field2;
}

public void DoSomething()
{
      MyStruct s = new MyStruct();
      GetStruct(ref s);

      s.Field1 = 100; //does unmanaged memory now have 100 in Field1 as well?
      s.Field2 = IntPtr.Zero; //does unmanaged memory now have a NULL pointer in field Field2 as well?
}
+4  A: 

No, the P/Invoke marshaller copied the unmanaged structure member values into the managed version of the structure. In general, the managed version of a structure is not in any way compatible with the unmanaged version of it. The memory layout is not discoverable, something the CLR uses to reorder fields to make the structure smaller. Marshaling is essential, you have to create a copy.

Modifying the structure is not possible with the given function signature since you let fill in the memory that's passed to it. The function itself already copies the structure. You can however party on the Field2 value since it is a raw pointer. If that points to a structure then marshal it yourself with Marshal.PtrToStructure(). Modify the managed copy of it and copy it back to unmanaged memory with Marshal.StructureToPtr(). Or access it directly with Marshal.ReadXxx() and WriteXxx().

Hans Passant
This is what I expect, but I'm really looking for some kind of confirmation of this on MSDN or the like.Also, a Pack=0 is just fine (it just means the platform default and is important to use for x86 and x64 deployment with the same code). See:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.pack.aspx
userx
This is really not a good place to find links, I recommend google.
Hans Passant
Restating what I said in my question isn't really an answer either :). I'm hoping for some kind of documentation which explains the behavior as implemented by Microsoft.
userx
A: 

CSharp Language Specification.doc pg 26

Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. Instead of dynamically allocating an object and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.

Since, there is nothing special about a 'struct' backing store, so one would not expect there to be annonymous marshalling operations going on behind the member assignments.

Les
I think this is the right answer. The fact that nothing hooks into the struct (or its fields) to make changes back to unmanaged memory when its fields are changed seems to conclusively answer this question.
userx