假设我有以下Rust库:
// lib.rs
#![crate_type = staticlib]
#[no_mangle]
pub extern fn do_something(number: i32) {
// something
}
#[no_mangle]
pub extern fn do_something_else(collection: &Vec<i32>) {
// something
}
Run Code Online (Sandbox Code Playgroud)
我知道,do_something要从C 调用,我只需要声明一个extern函数int32_t,但是可以调用do_something_else吗?如果是这样,怎么样?
libc 有一个函数返回一个不应该是 free()d 的字符串。可以读取用户当前目录,/etc/passwd但不应是 free()d。如果我从指针创建一个字符串,程序会立即中止
free(): invalid pointer
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
显然,代码是不安全的。
let pw = libc::getpwnam(username.as_ptr() as *const i8);
let cd = (*pw).pw_dir;
let len = libc::strlen(cd);
builder.current_dir(String::from_raw_parts(cd as *mut u8, len, len));
Run Code Online (Sandbox Code Playgroud)
我可以mem::forget(s)使用字符串,但会泄漏内存,至少长度必须存储在某处。我只需要防止释放底层原始字节。项目是一个服务器,所以我不能忽视泄漏。
在询问我应该如何在FFI边界释放内存之后,Rust reddit上的某个人建议我不是将我的结构包装在一个结构中Box,而是可以使用Vec::from_raw_parts从以下结构构造一个向量,并且可以安全地删除它:
#[repr(C)]
pub struct Array {
data: *const c_void,
len: libc::size_t,
}
Run Code Online (Sandbox Code Playgroud)
但是,from_raw_parts似乎需要*mut _数据,所以我不知道如何继续......