我正在尝试获取C库返回的C字符串,并通过FFI将其转换为Rust字符串.
mylib.c
const char* hello(){
return "Hello World!";
}
Run Code Online (Sandbox Code Playgroud)
main.rs
#![feature(link_args)]
extern crate libc;
use libc::c_char;
#[link_args = "-L . -I . -lmylib"]
extern {
fn hello() -> *c_char;
}
fn main() {
//how do I get a str representation of hello() here?
}
Run Code Online (Sandbox Code Playgroud) 这看起来微不足道,但我找不到办法.
例如,
fn f(s: &[u8]) {}
pub fn main() {
let x = "a";
f(x)
}
Run Code Online (Sandbox Code Playgroud)
无法编译:
error: mismatched types:
expected `&[u8]`,
found `&str`
(expected slice,
found str) [E0308]
Run Code Online (Sandbox Code Playgroud)
但是,文件指出:
strs的实际表示具有与切片的直接映射:&str与&[u8]相同.
在我为Cassandra C++驱动程序编写安全包装器的持续传奇中,当我使用以下签名调用C函数时,我的眼睛现在转向避免内存泄漏:
cass_string_init2(const char* data, cass_size_t length);
Run Code Online (Sandbox Code Playgroud)
要么
cass_string_init(const char* null_terminated);
Run Code Online (Sandbox Code Playgroud)
我尝试了一些名义上有效的方法,并产生了正确的结果,但我还没有找到一种方法来正确管理这些数据的生命周期.以下是两种示例方法.
pub fn str_to_ref(mystr:&str) -> *const i8 {unsafe{
let cstr = CString::from_slice(mystr.as_bytes());
cstr.as_slice().as_ptr()
}}
Run Code Online (Sandbox Code Playgroud)
和
pub fn str_to_ref(mystr: &str) -> *const i8 {
let l = mystr.as_bytes();
unsafe {
let b = alloc::heap::allocate(mystr.len()+1, 8);
let s = slice::from_raw_parts_mut(b, mystr.len()+1);
slice::bytes::copy_memory(s, l);
s[mystr.len()] = 0;
return b as *const i8;
}
}
Run Code Online (Sandbox Code Playgroud)
第一个做无效的内存访问,如
==26355== Address 0x782d140 is 0 bytes inside a block of size 320 free'd …Run Code Online (Sandbox Code Playgroud)