Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will struct modifications in C# affect unmanaged memory?

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?
}
like image 831
userx Avatar asked Sep 02 '10 18:09

userx


People also ask

Can structs be changed?

Unlike classes, a constant struct's properties cannot be changed—not from outside the struct, not even from within the struct's own methods, even if they're marked as mutating . Once a struct is constant, it is constant. It can't change.

Can a struct be extended?

We cannot directly extend structs but rather use a concept called composition where the struct is used to form other objects.

Can struct have methods in C?

Contrary to what younger developers, or people coming from C believe at first, a struct can have constructors, methods (even virtual ones), public, private and protected members, use inheritance, be templated… just like a class .

Does structure support inheritance in C?

Yes. The inheritance is public by default.


1 Answers

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().

like image 74
Hans Passant Avatar answered Oct 09 '22 01:10

Hans Passant