如何在Rust中调用C语言的typedef结构体及相关函数?
在Rust中调用C语言的结构体与函数
我来帮你解决这个对接问题,核心关键点是Rust默认的结构体内存布局和C不一致,必须显式指定兼容规则才能正确对接C的PAIR结构体。下面一步步拆解实现:
1. 定义与C兼容的Rust结构体
C里的typedef struct在Rust中需要用#[repr(C)]属性标注,这个属性会强制Rust编译器按照C的内存布局规则来排列结构体字段,保证和C的PAIR内存结构完全匹配。
2. 正确声明C函数
注意两个细节:
- C的
pair_add接收的是PAIR*指针,在Rust中对应*const Pair(只读场景)或*mut Pair(可修改场景) - 你之前的
add函数声明少了一个参数,要补上对应C的两个int入参
完整的Rust示例代码
extern crate libc; use libc::c_int; // 定义和C的PAIR完全兼容的Rust结构体,#[repr(C)]是核心要求 #[repr(C)] #[derive(Debug, Copy, Clone)] struct Pair { x: c_int, y: c_int, } #[link(name = "adder")] extern "C" { // 对应C的int pair_add(PAIR * ppair); fn pair_add(ppair: *const Pair) -> c_int; // 对应C的int add(int, int); fn add(x: c_int, y: c_int) -> c_int; } fn main() { // 创建和C内存布局一致的Pair实例 let my_pair = Pair { x: 15, y: 25 }; // 调用外部C函数必须放在unsafe块中(Rust无法保证C函数的安全性) unsafe { let pair_sum = pair_add(&my_pair as *const Pair); println!("pair_add计算结果: {}", pair_sum); let simple_sum = add(8, 12); println!("add计算结果: {}", simple_sum); } }
3. 编译与运行说明
编译时要告诉Rust静态库libadder.a的位置,比如库文件在当前目录,用以下命令:
rustc your_rust_file.rs -L . -o rust_adder
运行生成的可执行文件:
./rust_adder
关键细节补充
#[repr(C)]:没有这个属性的话,Rust会用自身的内存布局规则,导致和C的结构体字段偏移、对齐方式不匹配,调用C函数时会出现内存错误unsafe块:调用外部C函数属于不安全操作,因为Rust无法校验C函数的行为(比如空指针访问、内存越界),所以必须显式包裹在unsafe中- 指针类型选择:如果C函数只是读取结构体内容,用
*const Pair;如果需要修改结构体,就用*mut Pair对应C的PAIR*
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

