簡體   English   中英

為什么在 64 位平台上 BSTR 長度前綴為 4 個字節?

[英]Why is BSTR length prefix 4 bytes on 64-bit platforms?

似乎在 64 位平台上使用 8 字節長度的前綴是合理的。 如果我們可以處理超過 4Gb 的內存,為什么不允許使用 5Gb 字符串? 答案只是“按規范”還是有一些我不知道的互操作性/向后兼容性原因? 謝謝。

BSTR數據類型是標准的 COM 字符串數據類型。 更改長度前綴將無法在不同位數的進程之間安全地移動字符串(或至少使其變得更加復雜)。 由於 COM 是唯一相關的跨位互操作基礎設施,因此有必要讓BSTR的行為方式與 32 位進程和 64 位進程相同。

這是一種權衡,強加 2GB 的“限制”以換取不同位元進程之間的字符串無障礙編組。

一個很好的理由是與平台 API 兼容,例如接受int長度的MultiByteToWideChar 還有更多的字符串 API 可以使用 32 位長度。

這實際上並不是真正的限制,因為我無法想象長度 >2GB 的BSTR將是解決問題的最佳方案的場景。

BSTR是一個以長度為前綴的字符串,所以第一個屬性是長度,而不是地址。 因此它不需要與指針大小相同,並且可以是應用程序足夠的大小

對於所有實際目的,4GB 對一個字符串來說已經足夠了,並且保持最大字符串大小相同可以讓您在進程之間毫無問題地傳遞字符串。 例如,如果長度是 64 位 Windows 上的 64 位類型,那么當您將 8GB 字符串從 64 位進程傳遞到 32 位進程時會發生什么? 字符串應該被截斷還是應該報告錯誤? 相同的前綴大小還可以提高向后兼容性

最重要的原因可能是為了讓 BSTR 可以繼續在VARIANT旅行。 你會從定義注意到tagVARIANT在OAIDL.H的bstrVal成員似乎是其他類型的聯盟的一部分,而是保存它的長度在哪里呢? 答案是在wReserved2 / wReserved3的成員VARIANT結構立即先於bstrVal在存儲器部件。 那里有 3 個保留字,所以理論上 BSTR 的長度可以擴展到 6 個字節,但是如果它變得更大,它將覆蓋VARTYPE成員並且 VARIANT 將不再起作用。 所以BSTR即使在 64 位平台上也有長度限制,以便它可以繼續在VARIANT傳播。

擁有大量總大小超過 2GiB 的對象有用的應用程序范圍遠大於擁有任何單個對象超過 2GiB 的應用程序范圍。 即使對 64 位值的單個操作並不比對 32 位值的操作更昂貴,但適合每一級緩存的 32 位值的數量同樣是 64 位值的數量的兩倍。 因此,如果沒有使用 64 位值來保存對象大小的充分理由,讓平台將單個對象限制為 2GiB 是一個完全合理的設計決策,特別是因為不是設計用於處理更大對象的代碼通常會出現故障如果在不拒絕嘗試創建大於 2GiB 的對象的系統上運行,則很容易產生安全漏洞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM