I have a device that transmits binary data. To interpret the data I have defined a struct
that matches the data format. The struct
has a StuctLayoutAttribute
with LayoutKind.Sequential
. This works as expected, e.g:
[StructLayout(LayoutKind.Sequential)]
struct DemoPlain
{
public int x;
public int y;
}
Marshal.OffsetOf<DemoPlain>("x"); // yields 0, as expected
Marshal.OffsetOf<DemoPlain>("y"); // yields 4, as expected
Marshal.SizeOf<DemoPlain>(); // yields 8, as expected
Now I wish to treat one struct similar to an other struct, so I experimented with the structure implementing an interface:
interface IDemo
{
int Product();
}
[StructLayout(LayoutKind.Sequential)]
struct DemoWithInterface: IDemo
{
public int x;
public int y;
public int Product() => x * y;
}
Marshal.OffsetOf<DemoWithInterface>("x").Dump(); // yields 0
Marshal.OffsetOf<DemoWithInterface>("y").Dump(); // yields 4
Marshal.SizeOf<DemoWithInterface>().Dump(); // yields 8
To my surprise the offsets and size of DemoWithInterface
remain the same as DemoPlain
and converting the same binary data from the device to either an an array of DemoPlain
or an array of DemoWithInterface
both work. How is this possible?
C++ implementations often use a vtable (see Where in memory is vtable stored?) to sore virtual methods. I believe that in C# methods published in an interface, and methods that are declared virtual
, are similar to virtual methods in C++ and that it requires something similar to a vtable to find the correct method. Is this correct or does C# do it completely different? If correct, where is the vtable like structure stored? If different, how is C# implemented with respect to interface inheritance and virtual methods?