2011-03-31 73 views
0

大家好,如何在C#中定義TBBUTTON結構?

的TBBUTTON結構是在MSDN的定義如下:

typedef struct { 
    int  iBitmap; 
    int  idCommand; 
    BYTE  fsState; 
    BYTE  fsStyle; 
#ifdef _WIN64 
    BYTE  bReserved[6]; 
#else 
#if defined(_WIN32) 
    BYTE  bReserved[2]; 
#endif 
#endif 
    DWORD_PTR dwData; 
    INT_PTR iString; 
} TBBUTTON, *PTBBUTTON, *LPTBBUTTON; 

我需要使用這個結構做了一些互操作在C#。如何複製這個怪物,以便在爲AnyCPU編譯時正確定義它?谷歌顯然充滿了危險的錯誤信息!

回答

1

啊哈,我知道必須有一種方法。這裏,它是:

[StructLayout(LayoutKind.Sequential)] 
public struct TBBUTTON { 
    public int iBitmap; 
    public int idCommand; 
    [StructLayout(LayoutKind.Explicit)] 
    private struct TBBUTTON_U { 
     [FieldOffset(0)] public byte fsState; 
     [FieldOffset(1)] public byte fsStyle; 
     [FieldOffset(0)] private IntPtr bReserved; 
    } 
    private TBBUTTON_U union; 
    public byte fsState { get { return union.fsState; } set { union.fsState = value; } } 
    public byte fsStyle { get { return union.fsStyle; } set { union.fsStyle = value; } } 
    public UIntPtr dwData; 
    public IntPtr iString; 
} 

Marshal.SizeOf在x86處理回到在x64進程32和20,一切都結束了,它應該當我通過這SendMessage。我知道你可以做到,C#!

+0

感謝分享! – 2011-06-05 14:36:56

2

最好的辦法是定義兩個版本,一個用於32位,一個用於64位。

public struct TBBUTTON32 
{ 
    int  iBitmap; 
    int  idCommand; 
    byte  fsState; 
    byte  fsStyle; 
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)] 
    byte[] bReserved; 
    UIntPtr dwData; 
    IntPtr iString; 
} 

64位版本是相同的,但在保留字節數組上使用SizeConst = 6

然後你需要在運行時在它們之間切換。你的C#代碼必須檢測它是否以32或64位進程運行。

+0

呃...有沒有辦法避免這種情況?當然,編譯時必須有一種方法... – 2011-03-31 16:54:35

+1

如果你使用AnyCPU,那麼你不可避免地延遲運行時間的決定 – 2011-03-31 17:02:21

+0

這是否回答你的問題? – 2011-03-31 18:52:43