我已經收集到參考與指標不同,實際上它們有一些非常重要的區別,例如對齊保證、空值保證和別名保證,因此,如果你有一個打算使用的函式跨越采用原始指標的 FFI 邊界,您通常應在簽名中使用原始指標以避免潛在問題。
Option<&T>但是,在這樣的函式簽名中使用參考(或類似的東西)是否可以接受?例如,如果您將 API 與定義明確的規范系結,該規范說“*T必須有效或未定義行為”,您是否仍然會遇到使用參考代替簽名中的指標的問題?
uj5u.com熱心網友回復:
使用普通參考而不是指標總是安全的,只要指標的行為與參考一樣。正如書上所說:
可以安全地假定參考是直接指向 type 的不可空指標。但是,不能保證打破借用檢查或可變性規則是安全的,因此如果需要,最好使用原始指標 (*),因為編譯器無法對它們做出盡可能多的假設。
此外,正如參考資料所說:
指標和參考具有相同的布局。
如果您有共享參考并且 FFI 背后的函式不將其視為 a ,則會出現問題,也就是說,改變包含別名的任何內容(例如 a中可以通過訪問的欄位)。那是因為&Tconst *T&TU&T
如果你有一個參考 &T,那么通常在 Rust 中,編譯器會根據 &T 指向不可變資料的知識來執行優化。改變該資料,例如通過別名或將 &T 轉換為 &mut T,被認為是未定義的行為。
也就是說,編譯器將始終假設僅存在&T不能T改變(不考慮UnsafeCell)。實際上,編譯器會假設如果 a作為引數存在, FFI 函式不會改變。正如 nomicon 所建議的那樣,優先選擇和超過單純的參考是一種很好的做法,因為編譯器可以推斷出原始指標的來源(例如,如果您嘗試從 a派生 a ,它將捕獲)。因此,強烈建議您的 FFI 定義是 const 正確的;例如,一個假裝接受但實際上修改該引數的函式可以在編譯器無法捕獲的情況下呼叫或 呼叫。T&T*const T*mut T*mut T&Tconst *&T*const T
當涉及到單個型別時,互操作性取決于型別本身。這部書有一整節關于這方面的內容。一般來說:
只有當 #[repr(C)] 屬性應用于結構時,Rust 才保證結構的布局與 C 中的平臺表示兼容。
不過,這只能保證您在 C 中撰寫的型別布局與在 Rust 中的型別布局相同。您通常不能假設 Rust 型別會像在 C 中那樣表現。但是,在Optionor的特定示例中Box,Rust 實作std 確實提供了這樣的保證;另請參見此處和此處( Box<T> is guaranteed to be represented as a single pointer and is also ABI-compatible with C pointers (i.e. the C type T*)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/509955.html
標籤:指针锈菲
上一篇:將結構陣列傳遞給C中的函式
