Rust/C 互操作样例项目
基于 Rust 与 C 互操作的示例,覆盖三种场景:C 调用 Rust、Rust 调用 C、内联汇编。例子精简,仅说明机制。
前置条件
- Rust(
rustup安装) - gcc、make
- 本机运行需 x86_64 才能执行内联汇编示例(非 x86_64 时 asm_demo 使用纯 Rust 实现,测试仍通过)
- 可选:Docker(x86_64 镜像,用于一致环境与 CI)
项目结构
rust_c_ffi_sample/
├── Cargo.toml # workspace
├── README.md
├── Dockerfile # x86_64: rust + gcc + make
├── scripts/
│ └── run_tests.sh # 编译 + 测试 + 运行 c_example
├── .github/workflows/
│ └── ci.yml # CI:Docker 内执行 run_tests.sh
├── crates/
│ ├── ffi_lib/ # 被 C 调用
│ │ ├── src/lib.rs
│ │ └── include/ffi_lib.h
│ ├── ffi_caller/ # Rust 调用 C
│ │ ├── build.rs
│ │ ├── src/main.rs
│ │ └── c_src/
│ └── asm_demo/ # 内联汇编(x86_64)
│ └── src/lib.rs
└── c_example/ # C 程序,链接 ffi_lib
├── main.c
└── Makefile
模块与依赖关系
- Workspace(根目录
Cargo.toml)仅包含三个 crate:ffi_lib、ffi_caller、asm_demo。三者之间无 Cargo 依赖,各自独立。 - ffi_lib:被 C 侧调用。仅依赖
libc。产出libffi_lib.so/.dylib与libffi_lib.a,供 C 程序链接。 - ffi_caller:Rust 调用 C。无其它 crate 依赖;通过
build.rs编译并链接本 crate 下的 C 源码(c_src/*.c),不依赖ffi_lib。 - asm_demo:内联汇编示例。无依赖,独立库。
- c_example:非 Cargo 成员,为独立 C 工程。构建时先执行
cargo build -p ffi_lib,再使用gcc -lffi_lib链接target/debug中的libffi_lib,因此仅依赖 ffi_lib 的编译产物,与ffi_caller、asm_demo无关系。
c_example (C) ──链接──► ffi_lib (Rust cdylib/staticlib)
│
ffi_caller (Rust) ──build.rs 编译并链接──► c_src/*.c(本 crate 内 C)
asm_demo (Rust) (无外部依赖)
场景说明
1. C 调用 Rust(ffi_lib + c_example)
- ffi_lib:
cdylib/staticlib,导出add、concat_strings/free_rust_string、Point/distance、apply_callback、rust_hello、init_rust_library。使用#[no_mangle]、extern "C"、#[repr(C)],字符串遵循“谁分配谁释放”。 - include/ffi_lib.h:与上述 API 一致的 C 声明。
- c_example:C 程序包含
ffi_lib.h,链接libffi_lib,调用上述函数。编译产物为c_example_binary。
2. Rust 调用 C(ffi_caller)
- build.rs:用
cc编译c_src/math.c、c_src/string.c,include("c_src")。 - c_src:极简 C 实现(
c_add、c_scale_array、c_duplicate_string/c_free_string)。 - main.rs:
extern "C"声明并调用,带简单安全包装与单元测试。
3. 内联汇编(asm_demo)
- 仅 x86_64 使用
asm!(asm_add、bswap_u64);其他架构为纯 Rust 实现。 - 单元测试断言返回值,在 x86_64 下会执行真实汇编。
本地运行
# 进入项目根
cd rust_c_ffi_sample
# 运行全部测试与 c_example
./scripts/run_tests.sh脚本依次执行:cargo test --workspace、cargo build -p ffi_lib、cd c_example && make && ./c_example_binary。
仅跑 Rust 测试:
cargo test --workspace仅构建并运行 C 示例:
cargo build -p ffi_lib
cd c_example && make run可执行文件名为 c_example_binary(由 c_example/Makefile 生成)。
Docker
在 x86_64 环境下构建并运行测试(内联汇编会真实执行):
docker build --platform linux/amd64 -t rust-ffi .
docker run --rm rust-ffi容器内默认执行 ./scripts/run_tests.sh。
自动化测试与 CI
- scripts/run_tests.sh:顺序执行 workspace 测试、构建 ffi_lib、在
c_example下make并运行./c_example_binary;任一失败则退出。 - GitHub Actions(
.github/workflows/ci.yml):在push/pull_request到main或master时,构建上述 Docker 镜像(--platform linux/amd64),并在容器内执行./scripts/run_tests.sh。
文档
- docs/ANALYZE.md:技术分析文档,详细说明项目中用到的 ABI、类型对应、字符串/结构体/回调约定、build.rs 与链接流程、内联汇编操作数与条件编译等。
参考
更多 ABI、类型对应与细节可参考项目配套草稿文档(若有 draft.txt 等)。
On this page
Contributors
Created February 22, 2026
Updated February 22, 2026