Publico el tema aquí, por que creo que me podrá servir de más ayuda.
Estoy tratando de implementar la estructura DEVMODE en C#:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183565%28v=vs.85%29.aspx
( y no me sirven las implementaciones de pinvoke.net u otros ejemplos online, ya que todas las que he visto hasta ahora son erroneas o desactualizadas en algún sentido )
He estado comparando los offsets en C++ y C#, en C++ con la macro offsetof y en C# con la función Marshal.OffsetOf, hasta llegar al miembro dmFields todo es correcto;
el problema que tengo, es que el offset del miembro dmColor es 60 en C++, mientras que en mi implementación es 68, esto quiere decir que mi implementación de los miembros de la primera union es incorrecta.
Según un experto en código no administrado, mi representación de las unions y el enfoque que le stoy dando es correcto, pero no debe ser del todo así, ya que las posiciones/offsets son distintas.
Código
[StructLayout(LayoutKind.Sequential)] public struct DevMode { private const int CchDeviceName = 32; private const int CchFormName = 32; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CchDeviceName)] public string DeviceName; public short SpecVersion; public short DriverVersion; public short Size; public short DriverExtra; public DeviceModeFields Fields; public UnionDevMode1 test1; public short Color; public short Duplex; public short YResolution; public short TTOption; public short Collate; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CchFormName)] public string FormName; public short LogPixels; public int BitsPerPixel; public int PixelsWidth; public int PixelsHeight; public UnionDevMode2 test2; public int DisplayFrequency; public int IcmMethod; public int IcmIntent; public int MediaType; public int DitherType; public int Reserved1; public int Reserved2; public int PanningWidth; public int PanningHeight; } [StructLayout(LayoutKind.Explicit)] public struct UnionDevMode1 { [FieldOffset(0)] public SubUnionDevMode1 subUnion1; [FieldOffset(0)] public SubUnionDevMode2 subUnion2; } [StructLayout(LayoutKind.Sequential)] public struct SubUnionDevMode1 { public short Orientation; public short PaperSize; public short PaperLength; public short PaperWidth; public short Scale; public short Copies; public short DefaultSource; public short PrintQuality; } [StructLayout(LayoutKind.Sequential)] public struct SubUnionDevMode2 { public Win32.Types.Point Position; public DeviceModeDisplayOrientation DisplayOrientation; public int DisplayFixedOutput; } [StructLayout(LayoutKind.Explicit)] public struct UnionDevMode2 { [FieldOffset(0)] public int DisplayFlags; [FieldOffset(0)] public int Nup; }
El problema está en el miembro UnionDevMode1 , o al menos todo me indica eso, mejor dicho en alguno de los miembros de la estructura SubUnionDevMode1 o SubUnionDevMode2 , sin embargo, me he asegurado de que los types ocupan el mismo tamaño que en C++, vease:
POINTL = 8 bytes.
Win32.Types.Point = 8 bytes.
DeviceModeFields = int (4 bytes)
DeviceModeDisplayOrientation = int (4 bytes)
Teniendo esto en cuenta, ¿alguien es capaz de ver en lo que estoy fallando?.