Offests de los miembros de la estructura DEVMODE

Iniciado por Eleкtro, 13 Diciembre 2015, 15:56 PM

0 Miembros y 1 Visitante están viendo este tema.

Eleкtro

Hola

Me gustaría saber si alguien con experiencia en C++ podría indicarme los offests de los miembros de la estructura DEVMODE:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183565%28v=vs.85%29.aspx

Esto es por que estoy tratanto de trasladar las unions de dicha estructura a .Net, pero necesito saber los offsets de los miembros en C++ para comparar el resto de miembros, ya que algo hice mal, probablemente el tamaño de alguno de mis miembros declarados sea incorrecto en comparación con el tamaño definido en la estructura de C++.

Me han comentado que esto se hace con la macro offsetof:

Creo que no pido mucho, debe ser una cosa sencilla para quien maneje C++, pero si me equivoco disculpen y diganme más o menos como podría hacerlo yo mismo...

Saludos








fary

#1
En C#

Código (csharp) [Seleccionar]
Structure DEVMODE
   Public Const CCHDEVICENAME As Integer = 32
   Public Const CCHFORMNAME As Integer = 32

   <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCHDEVICENAME)> _
   <System.Runtime.InteropServices.FieldOffset(0)> _
   Public dmDeviceName As String
   <System.Runtime.InteropServices.FieldOffset(32)> _
   Public dmSpecVersion As Int16
   <System.Runtime.InteropServices.FieldOffset(34)> _
   Public dmDriverVersion As Int16
   <System.Runtime.InteropServices.FieldOffset(36)> _
   Public dmSize As Int16
   <System.Runtime.InteropServices.FieldOffset(38)> _
   Public dmDriverExtra As Int16
   <System.Runtime.InteropServices.FieldOffset(40)> _
   Public dmFields As DM
   <System.Runtime.InteropServices.FieldOffset(44)> _
   Private dmOrientation As Int16
   <System.Runtime.InteropServices.FieldOffset(46)> _
   Private dmPaperSize As Int16
   <System.Runtime.InteropServices.FieldOffset(48)> _
   Private dmPaperLength As Int16
   <System.Runtime.InteropServices.FieldOffset(50)> _
   Private dmPaperWidth As Int16
   <System.Runtime.InteropServices.FieldOffset(52)> _
   Public dmScale As Int16
   <System.Runtime.InteropServices.FieldOffset(54)> _
   Public dmCopies As Int16
   <System.Runtime.InteropServices.FieldOffset(56)> _
   Private dmDefaultSource As Int16
   <System.Runtime.InteropServices.FieldOffset(58)> _
   Private dmPrintQuality As Int16
   <System.Runtime.InteropServices.FieldOffset(44)> _
   Public dmPosition As POINTL
   <System.Runtime.InteropServices.FieldOffset(52)> _
   Public dmDisplayOrientation As Int32
   <System.Runtime.InteropServices.FieldOffset(56)> _
   Public dmDisplayFixedOutput As Int32
   <System.Runtime.InteropServices.FieldOffset(60)> _
   Public dmColor As Short
   <System.Runtime.InteropServices.FieldOffset(62)> _
   Public dmDuplex As Short
   <System.Runtime.InteropServices.FieldOffset(64)> _
   Public dmYResolution As Short
   <System.Runtime.InteropServices.FieldOffset(66)> _
   Public dmTTOption As Short
   <System.Runtime.InteropServices.FieldOffset(68)> _
   Public dmCollate As Short
   <System.Runtime.InteropServices.FieldOffset(72)> _
   <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCHFORMNAME)> _
   Public dmFormName As String
   <System.Runtime.InteropServices.FieldOffset(102)> _
   Public dmLogPixels As Int16
   <System.Runtime.InteropServices.FieldOffset(104)> _
   Public dmBitsPerPel As Int32
   <System.Runtime.InteropServices.FieldOffset(108)> _
   Public dmPelsWidth As Int32
   <System.Runtime.InteropServices.FieldOffset(112)> _
   Public dmPelsHeight As Int32
   <System.Runtime.InteropServices.FieldOffset(116)> _
   Public dmDisplayFlags As Int32
   <System.Runtime.InteropServices.FieldOffset(116)> _
   Public dmNup As Int32
   <System.Runtime.InteropServices.FieldOffset(120)> _
   Public dmDisplayFrequency As Int32
End Structurecode


ó:

Código (csharp) [Seleccionar]
[/ [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
    struct DEVMODE
    {
        public const int CCHDEVICENAME = 32;
        public const int CCHFORMNAME = 32;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
        [System.Runtime.InteropServices.FieldOffset(0)]
        public string dmDeviceName;
        [System.Runtime.InteropServices.FieldOffset(32)]
        public Int16 dmSpecVersion;
        [System.Runtime.InteropServices.FieldOffset(34)]
        public Int16 dmDriverVersion;
        [System.Runtime.InteropServices.FieldOffset(36)]
        public Int16 dmSize;
        [System.Runtime.InteropServices.FieldOffset(38)]
        public Int16 dmDriverExtra;
        [System.Runtime.InteropServices.FieldOffset(40)]
        public DM dmFields;

        [System.Runtime.InteropServices.FieldOffset(44)]
        Int16 dmOrientation;
        [System.Runtime.InteropServices.FieldOffset(46)]
        Int16 dmPaperSize;
        [System.Runtime.InteropServices.FieldOffset(48)]
        Int16 dmPaperLength;
        [System.Runtime.InteropServices.FieldOffset(50)]
        Int16 dmPaperWidth;
        [System.Runtime.InteropServices.FieldOffset(52)]
        Int16 dmScale;
        [System.Runtime.InteropServices.FieldOffset(54)]
        Int16 dmCopies;
        [System.Runtime.InteropServices.FieldOffset(56)]
        Int16 dmDefaultSource;
        [System.Runtime.InteropServices.FieldOffset(58)]
        Int16 dmPrintQuality;

        [System.Runtime.InteropServices.FieldOffset(44)]
        public POINTL dmPosition;
        [System.Runtime.InteropServices.FieldOffset(52)]
        public Int32 dmDisplayOrientation;
        [System.Runtime.InteropServices.FieldOffset(56)]
        public Int32 dmDisplayFixedOutput;

        [System.Runtime.InteropServices.FieldOffset(60)]
        public short dmColor;
        [System.Runtime.InteropServices.FieldOffset(62)]
        public short dmDuplex;
        [System.Runtime.InteropServices.FieldOffset(64)]
        public short dmYResolution;
        [System.Runtime.InteropServices.FieldOffset(66)]
        public short dmTTOption;
        [System.Runtime.InteropServices.FieldOffset(68)]
        public short dmCollate;
        [System.Runtime.InteropServices.FieldOffset(72)]
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
        public string dmFormName;
        [System.Runtime.InteropServices.FieldOffset(102)]
        public Int16 dmLogPixels;
        [System.Runtime.InteropServices.FieldOffset(104)]
        public Int32 dmBitsPerPel;
        [System.Runtime.InteropServices.FieldOffset(108)]
        public Int32 dmPelsWidth;
        [System.Runtime.InteropServices.FieldOffset(112)]
        public Int32 dmPelsHeight;
        [System.Runtime.InteropServices.FieldOffset(116)]
        public Int32 dmDisplayFlags;
        [System.Runtime.InteropServices.FieldOffset(116)]
        public Int32 dmNup;
        [System.Runtime.InteropServices.FieldOffset(120)]
        public Int32 dmDisplayFrequency;
    }
code]
Un byte a la izquierda.

Eleкtro

#2
fary, gracias por contestar pero esa definición es erronea. Sigo necesitando los offsets en C++.

¿Ese código lo sacaste de pinvoke.net, verdad?. Ya la probé recientemente, pero ni siquiere tiene los unions, de hecho, el autor ni siquiera debería haber declarado los miembros de forma explícita.

Debería ser más bien así:
Código (csharp) [Seleccionar]
[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;

}


... Solo que algún miembro de mis declaraciones tiene un tamaño/posición incorrecto, necesito comparar los offsets.

Estoy descargando la IDE code::blocks, pero nunca hice esto en C++, de hecho practicamente he manejado C++ solo un par de veces, ya veremos si lo consigo averiguar...

Saludos








fary

En realidad no tiene que llevar los union, fijate en este mismo ejemplo de la msdn:

https://msdn.microsoft.com/en-us/library/aa251430(v=vs.60).aspx

typedef struct _devicemode {    /* dvmd */
   TCHAR  dmDeviceName[32];
   WORD   dmSpecVersion;
   WORD   dmDriverVersion;
   WORD   dmSize;
   WORD   dmDriverExtra;
   DWORD  dmFields;
   short  dmOrientation;
   short  dmPaperSize;
   short  dmPaperLength;
   short  dmPaperWidth;
   short  dmScale;
   short  dmCopies;
   short  dmDefaultSource;
   short  dmPrintQuality;
   short  dmColor;
   short  dmDuplex;
   short  dmYResolution;
   short  dmTTOption;
   short  dmCollate;
   TCHAR  dmFormName[32];
   WORD   dmUnusedPadding;
   USHORT dmBitsPerPel;
   DWORD  dmPelsWidth;
   DWORD  dmPelsHeight;
   DWORD  dmDisplayFlags;
   DWORD  dmDisplayFrequency;
} DEVMODE;


WORD = 2 bytes
DWORD = 4 bytes
TCHAR [32] = 32 bytes
USHORT = 2 bytes
short = 2 bytes

Espero que ahora si lo puedas resolver.
Un byte a la izquierda.

Eleкtro

#4
Pero claramente la definición actual tiene más miembros.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183565%28v=vs.85%29.aspx

Gracias por tu tiempo.

Lo estoy comprobando con este código de ejemplo que encontré:
http://www.cplusplus.com/reference/cstddef/offsetof/

Código (cpp) [Seleccionar]
#include <windows.h>

int main ()
{
 printf ("offsetof is %d\n",(int)offsetof(DEVMODE,dmColor));
 return 0;
}


Lo único tedioso o incómodo es que al no haber Reflection en C++ voy comprobando miembro por miembro, uno por uno, jeje. Aunque tampoco se si habrá alguna otra posible manera de enumerar los miembros de una estructura.

PD: En estos momentos maldigo haber capado mi VS de las características y el compiler de C++, no me gustan nada las IDEs alternativas de C++.

Saludos