You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:37:22