2014-09-04 104 views
0

根據http://referencesource.microsoft.com/#mscorlib/system/runtime/interopservices/safebuffer.cs爲什麼使用Marshal.AlignedSizeOfStruct <T>代替SafeBuffer.WriteArray中的Marshal.SizeOfStruct <T><T>和SafeBuffer.ReadArray <T>?

SafeBuffer使用結構類型的對齊大小而不是結構類型的實際大小。看起來這會在編寫需要密集打包的結構數組時以及從緩衝區中先前存在的密集打包的非結構數組結構讀取時導致對齊問題。在第一種情況下,使用對齊而不是實際大小會導致不需要的填充字節。第二,數據被破壞。我有兩個問題(4真的,但3都跟):

  1. 有沒有解決這個其他的方式比手動校準使用順序調用訪問SafeBuffer.Write<T>/Read<T>(這是比較慢),或開溝SafeBuffer類(因此完全不錯UnmanagedMemoryAccessor類)?
  2. 這種選擇背後的原因是什麼?爲什麼CLR在非託管內存上強制執行它自己的對齊要求?爲什麼這不被視爲一個錯誤?

回答

1

Hmya,對這些問題的回答總是主觀的,我們沒有.NET Framework設計師在這裏貢獻他們的設計會議筆記給我們。但你可以放心地假設這是而不是一個錯誤,這是一個很大的痛苦。毫無疑問,在.NET中支持MMF需要這麼長時間的原因至少有一個。

每個人都喜歡忽略或希望結構包裝和對齊的細節。 CLR在隱藏它們方面做了非常了不起的工作。但是,這種壓力在這裏停止,無法再忽視它們。冷酷的事實是,讓每個人都快樂是完全不可能的。框架沒有合理的方式來猜測MMF另一端的代碼是什麼樣的。不可知的是,MMF完全過於簡單,無法支持任何元數據。在一端有32位進程而另一端有64位進程的清除故障模式下,他們使用不同的對齊選擇,4對8。更多,特別是如果它是使用其自己的#pragma包的另一端的本機代碼。

鑑於框架永遠無法100%正確,他們選擇了至少使.NET代碼在任何一方運行時都是正確和有效的。一個完全合理的選擇。

唯一真正的缺陷是文檔缺乏。當您需要與本機代碼進行互操作時,您的頭痛。嘗試和錯誤是現在唯一的好方法。或者詢問一個關於特定問題的問題,當然你也有:)

+0

_「該框架沒有合理的方法來猜測MMF另一側的代碼是什麼樣的」_I ____ _ _ _ _ _ _ _ _ _ m不使用內存映射文件。我使用了一個自定義的SafeBuffer子類來包裝一些無人的內存。 B.如果CLR無法猜測,它至少可以讓客戶端指定它想要的對齊方式。事實上,我應該能夠通過StructLayoutAttribute來設置結構的大小和內存佈局,這表明它在轉換爲指針時會受到尊重。 – Benjamin 2014-09-04 18:50:46

+0

你當然在跟錯誤的人說話。改用微軟。或者只是編寫你自己的SafeBuffer版本。 – 2014-09-04 18:52:55

+0

我來這裏看看我是否脫離基地。對不起,如果它看起來像我爭論。無論如何,我最終可能會與微軟交談並編寫自己的版本。謝謝您的幫助。 – Benjamin 2014-09-04 19:59:33