2012-09-13 42 views
7

有沒有一種方法可以有條件地應用屬性結構?基於不同的結構屬性的32位或64位

如果機器32位我想如果機器應用此屬性

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

我想申請這個屬性

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

或可替代我可以用屬性...

0123替換一個值嗎?

32位(包= 2)

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

(包= 8)

[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]

我試圖用這個example但它的自定義屬性,不存在那些。

更新:

  • 我想comile到「任何CPU」
  • 的屬性是SHFILEOPSTRUCT並根據在所述處理器上使用或。
  • 我不想編譯兩個版本。
+1

你會靜態編譯程序64位和32位,還是你使用「任何CPU」,並希望在運行時表現不同? –

+0

如果只有'StructLayoutAttribute'類沒有密封。衛生署! – simonlchilds

+1

你可以用條件編譯指令來做到這一點。 –

回答

6

好問題。

我首先想到的答案是預處理器指令和32位和64位編譯程序集。您可以使用相同的代碼,即使是同一個項目,只是構建和部署根據目標系統上有兩個途徑:

#ifdef Bit32 
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)] 
#endif 
#ifdef Bit64 
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)] 
#endif 

這需要定義一個基於目標架構爲您的項目Bit32和Bit64編譯常數,並可能構建你的應用程序兩次。

如果你想在運行時做到這一點,我不認爲這是可能的,除非你在運行時動態地發出整個類。這些屬性可能只有固定的數據,並且它們不能在運行時有條件地應用(預處理器指令在編譯時運行,而不是在運行時運行)。

我認爲可以這樣做的唯一方法是將類定義複製到兩個名稱空間中,並根據Environment.Is64BitOperatingSystem屬性有條件地使用其中一個或另一個。您可以使用此屬性來有條件地控制您實例化哪個類,或選擇哪種創建策略(使用哪種工廠方法或相關模式),但不能在運行時條件控制屬性;他們的信息作爲元數據靜態編譯到程序集清單中。運行時本身特別使用這個特性來定義它如何將堆對象的成員存儲爲堆數據,並且您從未真正在用戶代碼中查找此屬性並使用它來定義行爲(從而忽略或指定條件包運行時的值)。

+0

+1。在運行時發出聽起來像有趣的方法。 –

+0

有趣的是,在臥室裏捆綁和ch咽的方式很有趣,絕對需要一定的心態才能這樣看待。 – KeithS

+0

是的,我應該更仔細地選擇我的話 - 在「令人興奮的,有趣的,冒險的,但不太可能有利可圖」的樂趣。我認爲「捆綁和窒息」是比較嚴酷的比較,除非是因爲真正的生產代碼決定採用這種方法。 –

0

我不認爲你可以這樣做。只是有2個結構,並提供了一種方法來轉換爲共享結構或類處理...

注意:你要求的功能是非常奇怪的(不同的基於JIT類型的顯式佈局,發生在運行時)。在大多數情況下,這用於字節的物理佈局,匹配一些衆所周知的獨立於應用程序的固定協議。您可以將您的案例視爲針對x86/x64情況具有2種不同的協議/ interop,並對2種結構感到滿意。

1

創建兩個不同的構建目標(一個用於32位,一個用於64位),爲每個(x86爲一個,x86_64爲另一個)添加一個條件編譯符號,並圍繞結構定義使用#ifdef

+0

沒有更多upvotes:(....我認爲這種方法將工作 - 編譯相同的類/結構的2個版本,並在運行時動態加載一個取決於當前進程的位。這樣你有一個結構/類和可以很容易地在代碼的其餘部分使用它,而不會奇怪ifdefs –

+0

@Alexei Levenkov - 應該說,我不是真的想編譯兩個版本。 – Rob