2010-05-19 12 views
0

J'ai union à l'intérieur la structure et la structure ressemblequestion de rassemblement syndical en C#

struct tDeviceProperty { 

    DWORD Tag; 
    DWORD Size;  
    union _DP value;  
}; 

typedef union _DP 
{ 
     short int   i;  
     LONG    l;  
     ULONG    ul;  
     float    flt;  
     double    dbl;  
     BOOL  b;   
     double    at;  
     FILETIME   ft;  
     LPSTR    lpszA; 
     LPWSTR    lpszW; 
     LARGE_INTEGER  li;  
     struct tBinary bin;  
     BYTE    reserved[40]; 
} __UDP; 


struct tBinary { 
    ULONG size;  
    BYTE * bin;  
}; 

du bac structure tBinary doit être converti en TImage (structure est donnée ci-dessous)

struct tImage { 
    DWORD x; 
    DWORD y; 
    DWORD z; 
    DWORD Resolution; 
    DWORD type; 
    DWORD ID; 
    diccid_t SourceID; 
    const void *buffer; 
    const char *Info; 
    const char *UserImageID; 
}; 

à utilise la même chose dans C# J'ai fait du marshaling mais ne donne pas de valeurs correctes lors de la conversion du pointeur en structure. Le code C# est suit,

tBinary tBin = new tBinary(); 
IntPtr tBinbuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(tBin)); 
Marshal.StructureToPtr(tBin.bin, tBinbuffer, false); 


tDeviceProperty tDevice = new tDeviceProperty(); 
tDevice.bin = tBinbuffer; 
IntPtr tDevicebuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(tDevice)); 
Marshal.StructureToPtr(tDevice.bin, tDevicebuffer, false); 

Battary tbatt = new Battary(); 
tbatt.value = tDevicebuffer; 
IntPtr tbattbuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(tbatt)); 
Marshal.StructureToPtr(tbatt.value, tbattbuffer, false); 

result = GetDeviceProperty(ref tbattbuffer); 

Battary v = (Battary)Marshal.PtrToStructure(tbattbuffer, typeof(Battary)); 

tDeviceProperty v2 = (tDeviceProperty)Marshal.PtrToStructure(tDevicebuffer, typeof(tDeviceProperty)); 

tBinary v3 = (tBinary)Marshal.PtrToStructure(tBinbuffer, typeof(tBinary)); 






[StructLayout(LayoutKind.Explicit)] 
public struct tDeviceProperty 
{ 
    [FieldOffset(0)] 
    [MarshalAs(UnmanagedType.U2)] 
    public ushort i; 
    [FieldOffset(2)] 
    [MarshalAs(UnmanagedType.I4)] 
    public int l; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.U4)] 
    public uint ul; 
    [FieldOffset(10)] 
    [MarshalAs(UnmanagedType.R4)] 
    public float flt; 
    [FieldOffset(14)] 
    [MarshalAs(UnmanagedType.R8)] 
    public double dbl; 
    [FieldOffset(22)] 
    [MarshalAs(UnmanagedType.I4)] 
    public int b; 
    [FieldOffset(26)] 
    [MarshalAs(UnmanagedType.R8)] 
    public double at; 
    [FieldOffset(34)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr ft; 
    [FieldOffset(42)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr lpszA; 
    [FieldOffset(43)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr lpszW; 
    [FieldOffset(45)] 
    [MarshalAs(UnmanagedType.U8)] 
    public ulong li; 
    [FieldOffset(53)] 
    [MarshalAs(UnmanagedType.Struct)] 
    public IntPtr bin; 
    [FieldOffset(61)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr reserved; 
} 


[StructLayout(LayoutKind.Sequential)] 
public struct tBinary 
{ 
    public int size; 
    public IntPtr bin; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct Battary 
{ 
    public uint Tag; 
    public uint Size; 
    public IntPtr value; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct tDiccBatteryStatus 
{ 
    public uint RefreshWear; 
    public uint TotalWear; 
    public ushort Voltage; 
    public ushort Battery; 
    public int BatteryOK; 
    public int NeedRefresh; 
    public int NeedChange; 
    public ushort Temperature; 
    public int Charge; 
    public byte State; 
    public byte ExternalPowered; 
    public int CapacityLeft; 
} 
+0

Quelle est votre question? – bentsai

+0

Ne pas obtenir les valeurs correctes ... lors de la conversion du pointeur en structure, les valeurs sont erronées. Quel peut être le problème? – senthil

Répondre

0

Je pense que la raison de l'échec est la déclaration tDeviceProperty. En fait, son membre value est une union, mais dans le tDeviceProperty vous appliquez un décalage augmently augmentant, alors qu'ils auront la même valeur. Ceci est dû au fait que les membres de l'union commencent au même décalage, partageant le même espace que les autres membres. La taille de l'union est déterminée par la taille maximale des champs déclarés dans l'union.

En effet, en utilisant votre code:

[StructLayout(LayoutKind.Explicit, Size =)] 
public struct tDeviceProperty 
{ 
    [FieldOffset(0)] 
    [MarshalAs(UnmanagedType.U2)] 
    public ushort i; 
    [FieldOffset(2)] 
    [MarshalAs(UnmanagedType.I4)] 
    public int l; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.U4)] 
    public uint ul; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.R4)] 
    public float flt; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.R8)] 
    public double dbl; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.I4)] 
    public int b; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.R8)] 
    public double at; 
    [FieldOffset(6)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr ft; 
    [FieldOffset(6)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr lpszA; 
    [FieldOffset(6)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr lpszW; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.U8)] 
    public ulong li; 
    [FieldOffset(6)] 
    [MarshalAs(UnmanagedType.Struct)] 
    public IntPtr bin; 
    [FieldOffset(6)] 
    //[MarshalAs(UnmanagedType.Struct)] 
    public IntPtr reserved; 
} 

Vérifiez aussi ma récente question/answer.