面试题答案
一键面试Rust的String
和C的char *
转换
- 从Rust的
String
转换为C的char *
:- 在Rust中,
String
是一个动态分配的字符串类型。要转换为char *
,通常需要将String
转换为CString
(来自libc::CString
),因为普通的String
可能包含空字符,而C字符串以空字符结尾。 CString
可以通过as_ptr
方法获取一个*const c_char
(c_char
是libc
中定义的C字符类型,对应C的char
),这就类似于C的char *
。- 示例代码:
- 在Rust中,
use std::ffi::CString;
use libc::c_char;
fn string_to_c_str(s: String) -> *const c_char {
let c_str = CString::new(s).expect("Failed to convert String to CString");
c_str.as_ptr()
}
- 从C的
char *
转换为Rust的String
:- 可以使用
CStr
(来自libc::CStr
)来安全地处理C字符串,然后将其转换为String
。 - 示例代码:
- 可以使用
use std::ffi::CStr;
use libc::c_char;
fn c_str_to_string(c_str: *const c_char) -> String {
let c_str = unsafe { CStr::from_ptr(c_str) };
c_str.to_str().expect("Failed to convert CStr to &str").to_string()
}
从C调用Rust函数传递char *
数组,Rust函数接收并处理
- 定义Rust函数:
- 使用
extern "C"
修饰符来标记函数,以便C代码可以调用。 - 函数参数可以是
*const c_char
,表示C字符串。 - 示例代码:
- 使用
use std::ffi::CStr;
use libc::c_char;
#[no_mangle]
pub extern "C" fn process_c_string(c_str: *const c_char) {
let c_str = unsafe { CStr::from_ptr(c_str) };
if let Ok(s) = c_str.to_str() {
println!("Processed string: {}", s);
} else {
println!("Invalid UTF - 8 string");
}
}
- C代码调用:
- 在C代码中,需要链接生成的Rust库(通常是动态库
.so
或静态库.a
)。 - 示例C代码:
- 在C代码中,需要链接生成的Rust库(通常是动态库
#include <stdio.h>
#include <stdlib.h>
// 假设Rust函数定义在一个名为libexample.so的库中
// 函数声明
extern void process_c_string(const char*);
int main() {
const char* str = "Hello from C";
process_c_string(str);
return 0;
}
需要注意的是,在实际使用中,从Rust获取的*const c_char
指针在使用完后,不能在Rust外部释放,因为Rust的内存管理和C的内存管理方式不同。同样,从C传递给Rust的char *
指针,Rust函数也不应该释放,除非明确约定由Rust管理内存。