2013-04-07 59 views
1

我正在做一些本地庫的互操作,它有一些非自然對齊功能,我想在.NET結構中模擬佈局。檢查這兩個結構中:如何設置.NET結構的非自然對齊?

public struct Int3 
{ 
    public int X; 
    public int Y; 
    public int Z; 
} 

public struct MyStruct 
{ 
    public short A; 
    public Int3 Xyz; 
    public short B; 
} 

所以,在.NET中,它使用自己的佈局規則創建的佈局,這是,定位是分鐘(的sizeof(primitiveSize),StructLayout.Pack)。所以MYSTRUCT的佈局將是:

[oo--] MyStruct.A (2 bytes data and 2 bytes padding) 
[oooo oooo oooo] MyStruct.Xyz (3 int, no padding) 
[oo--] MyStruct.B (2 bytes data and 2 bytes padding) 

我想要做的是,我想INT3的定位更改爲8個字節,喜歡的東西:

[StructLayout(Alignment = 8)] 
public struct Int3 { .... } 

然後MYSTRUCT的佈局會成爲:

[oo-- ----] MyStruct.A (2 bytes for data, and 6 bytes padding, to align next Xyz to 8 
[oooo oooo oooo ----] MyStruct.Xyz (4 bytes padding for alignment of 8) 
[oo-- ----] (6 bytes padding, because the largest alignment in this struct is 8) 

所以,我的問題是:

1)是否有.NET來控制n個這樣的屬性像這樣的自然對齊? 2)如果沒有這樣的內置屬性,我知道還有其他屬性,如StructLayout.Explict,OffsetAttribute,StructLayout.Size,StructLayout.Pack。有了這些屬性,我可以手動模擬這種佈局,但不便於使用。所以我的第二個問題是,有沒有辦法掛鉤到.NET結構佈局創建,我可以干預結構佈局?我的意思是,我可以創建一個自定義屬性來指定對齊方式,然後計算佈局,但我不知道如何幹涉.NET來使用該佈局。

問候,祥。

+0

不需要。您需要使用屬性。那有什麼問題? – 2013-04-07 11:10:28

+0

@CodyGray問題是,.NET會認爲Int3的對齊方式是4,因爲它只檢查每個成員是基本類型,在本例中爲int。但在某些本地代碼中,爲了獲得更好的性能,他們需要認爲Int3可以在8邊界甚至16字節邊界處對齊。所以.NET看起來沒有辦法看到非原始類型的對齊。 – 2013-04-07 11:57:42

+0

雖然我仍然不完全確定自己理解這個問題。爲什麼你不能只使用屬性來改變對齊方式?除非我誤解了這個問題,否則我認爲你正在尋找[StructLayout屬性的Pack字段](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.pack的.aspx)。像這樣:'[StrutLayout(LayoutKind。Sequential,Pack = 8)]' – 2013-04-07 12:01:24

回答

2

除了StructLayout.Explicit(它就是這樣的一種機制),沒有其他的方法可以像'你想要的那樣'掛鉤到.NET中。 Interop是一個相當特殊的需求,除了標準的WinAPI情況,你不應該期望它很容易。在你的情況下,除非你用這種不尋常的對齊方式處理真正大量的不同結構,最好用MyStruct上的StructLayout.Explicit進行長時間的拼寫。

+0

謝謝。我猜Google搜索後沒有其他辦法了。感謝您確認這一點。實際上,我在F#中編寫了一個CUDA語言翻譯器,因此CUDA C具有__align __(x)這樣的概念,並且如果使用StructLayout.Explicit,它可以工作,但需要更多工作來檢查佈局,而不僅僅是像CUDA只需將一個屬性附加到該結構。 – 2013-04-07 11:52:58

+0

看看Cudify如果你想擁有cuda的cuda for cuda http://cudafy.codeplex.com/ – 2013-04-07 14:20:16

+0

@MeirionHughes謝謝,我知道CUDAfy。其實我正在用F#爲CUDA創建一個新庫:https://www.quantalea.net/products/introduction/而在CUDAfy中,我沒有看到它們如何控制結構對齊,你知道該怎麼做在CUDAfy中? – 2013-04-07 14:56:34

0

幾乎任何結構都將作爲堆對象的一部分進行存儲(或者作爲類字段,或者作爲存儲爲類字段的結構的字段等等).net 32​​平臺將對象大對象堆到16字節邊界,但其他對象到4字節邊界。除非在LOH上手動分配對象,或者由於真正殘酷的黑客,恕我直言,這是一個超過999雙的陣列,沒有任何有意義的方式來確保任何比4字節對齊更具體的方式。即使在某個時刻一個未固定的結構是16字節對齊的,任何任意的GC循環都可能重新定位它並改變對齊。