rust c ffi
Rust C FFI
rust-bindgen: rust 调用 c
rust-bindgen 是在编译时由头文件生成绑定代码的工具。由它封装的库称为 xxx-sys
常量宏
对于形如 #define XX (int)0
这样的有类型转换的宏是不能自动生成绑定的,可以在 wrapper.h
中写
static const int _XX = XX;
来创建绑定。
libc: 系统库
c 类型
一般的类型在 std::os::raw
中,或者使用在 libc
中的重新绑定。
字符串
c 的字符串实际上是 &[u8]
数组,可以用 std::ffi::CString
和 std::ffi::CStr
, 其中 CString
拥有所有权, CStr
是借用。
指针
c 的常量指针 const int *
对应 *const i32
, 一般指针 int *
对应 *mut i32
. 两级指针 int **
对应 *mut *mut int
以此类推。
结构体
rust 中定义与 c 兼容的结构体的方法为
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct MyStruct {
pub a: ::std::os::raw::c_int,
}
sizeof
与 c 的 sizeof
相同的是 std::mem::sizeof
offsetof
使用 memoffset 的 offset_of!
宏来获得。
如果不希望结构体内存对齐,使用 #[repr(packed)]
问题解决
传递 argc, argv
extern crate libc;
use libc::{c_char, c_int, c_void};
use std::ffi::CString;
extern "C" {
fn foo(argc: *mut c_int, argv: *mut *mut *mut c_char);
}
fn main() {
let mut c_args: Vec<*mut c_char> = std::env::args()
.map(|arg| CString::new(arg).unwrap().into_raw())
.collect();
unsafe {
let mut c_argc: c_int = c_args.len() as c_int;
let mut c_argv: *mut *mut c_char = c_args.as_mut_ptr();
foo(&mut c_argc as *mut c_int, &mut c_argv);
}
}
评论
Comments powered by Disqus