7个版本
0.9.0 | 2024年5月6日 |
---|---|
0.8.8 | 2023年4月22日 |
0.8.6 |
|
0.8.5 |
|
0.3.0 |
|
#74 在 FFI
每月129次下载
18KB
186 行
无缝Rust FFI的不可见指针
利用泛型不可见指针实现Rust与C/C++的无缝FFI互操作性
概述
简化原始指针管理,将Rust结构体暴露为不可见指针,无缝实现Rust和C/C++函数之间的交互。此Crate通过cbindgen(使用parse.parse_deps = true
)生成用于参数的不可见C/C++结构体。
要全面了解Rust与其他语言的互操作性,请参阅Jake Goulding的Rust FFI Omnibus对象部分。
借出功能
通过激活lender
功能,函数如own_back<T>()
验证指针的有效性,确保其有效性。这意味着,它将由raw<T>()
返回。
示例
创建FFI以从C或C++使用Rust的struct
方法
struct Counter { value: u8 }
impl Counter {
pub fn new() -> Self { Self { value: 0 } }
pub fn add(&mut self, value: u8) { self.value += value }
pub fn get(&self) -> u8 { self.value }
}
/// Ownership will NOT control the heap-allocated memory until own it back.
#[no_mangle]
pub extern fn counter_new(value: u8) -> *mut Counter {
return opaque_pointer::raw(Counter::new())
.expect("Error trying to lend a pointer");
}
/// Drop (free memory of) Rust's Counter object as usually.
#[no_mangle]
pub extern fn counter_free(counter: *mut Counter) {
unsafe { opaque_pointer::own_back(counter) };
}
#[no_mangle]
pub extern fn counter_add(counter: *mut Counter, value: u8) -> bool {
let counter = unsafe { opaque_pointer::mut_object(counter) };
if counter.is_err() {
return false;
}
let counter = counter.unwrap();
counter.add(value);
// Here will NOT be dropped, the pointer continues been valid.
return true;
}
#[no_mangle]
pub extern fn counter_get(counter: *const Counter) -> u8 {
let counter = unsafe { opaque_pointer::object(counter) };
if counter.is_err() {
return 0;
}
let counter = counter.unwrap();
return counter.get();
// Here will NOT be dropped, the pointer continues been valid.
}
上一个示例在运行测试时进行编译。如果您有该代码的错误,请打开一个issue。
功能
std
:默认激活,对于c类型FFI是必需的。alloc
:如果没有std编译则需要。c-types
:C类型的FFI,需要std功能。
FFI函数中的panic & unwind
此创建返回结果以避免指针为空时的恐慌,如果您的FFI需要检查恐慌,请查看以下链接。
请参阅gtk-rs问题#78中的评论,以获取良好的简历示例。
目前,任何跨extern "C"函数的 unwind 都是未定义的行为(UB),即使这些函数碰巧是用 Rust 实现的也是如此。这是该工作组正在努力解决的问题之一。例如,这添加了对extern "C-unwind" ABI的支持,该ABI明确允许unwind(并且据我所知,通过extern "C"进行unwind会导致程序异常终止,就像应该那样)。
另请参阅Rust问题#58794中的评论和Rust问题#58760。
在此PR中,将默认值更改为extern函数中的默认终止。这是跟踪#[unwind(allowed)](和#[unwind(abort)])属性的稳定化。
此PR更改了生成代码的行为,使其默认为sound。如果extern fn发生unwind(通过panic进行)则程序立即终止。换句话说,任何extern fn都不能unwind。
以及Rust问题#52652。
这个UB在任何后续的发布说明书中都没有提及。
依赖项
约90KB