簡體   English   中英

將Rust特征傳遞給C

[英]Pass a Rust trait to C

我正在構建一個Rust庫,需要使用Rust對象調用一些C函數。 我有一個帶有調用C函數的函數的特性,C函數在Rust中定義如下:

extern {
    fn process_trait(my_trait: MyTrait);
}

這個想法是用戶可以為他的struct實現trait,然后調用C函數(基本上,C然后調用其他一些Rust,它會調用一些Trait函數)。 這里的錯誤是: the trait core::marker::Sized is not implemented for the type Self ,因為我將*self傳遞給process_trait。 難道我做錯了什么? 我嘗試改變這一點,甚至施法,我得到這個錯誤或錯誤的類型。

我認為問題是它應該是堆分配的,不是嗎? 我唯一要避免的是API看起來很難看。 用戶應該能夠

struct MyUnit;
impl MyTrait for MyUnit...
MyUnit.callC();

按值傳遞特征對象沒有意義,尤其是在與C交互時。實際類型(在C意義上)及其大小未知,並且對象內部沒有vtable。 您最有可能想要傳遞特征參考( &MyTrait )。 但是,特征對C來說是陌生的,因此會形成一個糟糕的界面。 雖然您可以在C中定義core::raw::TraitObject的等價物,但實際上對vtable執行任何操作都非常難看且易碎core::raw::TraitObject安全。

如果您在銹-C屏障需要多態,顯函數指針是一個更好的選擇。 你仍然可以擁有MyTraitcallC方法,它只是看起來不同的FFI部分。 可以將C庫回調與對象一起作為有效負載進行處理。

或者,傳遞前面提到的TraitObject (胖指針)但從不從C檢查它們,通過Rust中的(非特征)輔助函數調用方法:

extern fn call_method(obj: TraitObject) {
    let obj: &MyTrait = transmute(obj); // should be safe, but not tested
    obj.meth();
}

這避免了手動挖掘C中Rust vtable的麻煩。

暫無
暫無

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

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