2010-05-19 75 views
0

我有內部結構,工會和結構看起來像聯合編組問題

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;  
}; 

從tBinary結構箱具有轉換爲TImage中(如下結構給出)

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; 
}; 

到在c#中使用同樣的東西我已經完成了封送處理,但是在將指針轉換爲結構時沒有給出適當的值。 C#代碼如下,

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

你的問題是什麼? – bentsai 2010-05-19 15:23:11

+0

沒有得到正確的值......當從指針轉換爲結構時,值出錯了。可能是什麼問題? – senthil 2010-05-19 15:30:20

回答

0

我認爲失敗的原因是tDeviceProperty聲明。事實上,它的成員value是一個聯合,但在tDeviceProperty中,你應用constatly遞增偏移量,而它們應該具有相同的值。

這是因爲工會成員開始在相同的偏移量,共享其他成員相同的空間。聯合的大小由聯合中聲明的字段的最大大小決定。

事實上,使用代碼:

[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; 
} 

檢查也是我最近question/answer