关于 port-c-module
这项技能指导开发者将 C 模块移植到 Rust,涵盖代码分析、制定计划、FFI 集成和测试,面向 Redisearch Rust 代码库中的移植工作。
主要功能
- 01分析 C API、依赖和测试
- 02制定模块移植计划
- 03创建 Rust crate 和 FFI 封装
- 04将 Rust 代码接入 C 代码库
- 05测试 C 与 Rust 集成
适用场景
- 01规划 C 模块迁移到 Rust
- 02实现带 C 接口的 Rust 模块
- 03检查移植步骤和集成测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ redisearch/ redisearch --skill port-c-module安装后在 Claude Code 中输入/port-c-module确认已加载。
详细介绍
移植模块技能
将 C 模块移植到 Rust 的指南。
参数
要移植的模块名称应作为参数提供(例如,/port-module triemap)。
要移植的模块:$ARGUMENTS
用法
开始将 C 模块移植到 Rust 时使用此技能。
说明
1. 分析 C 代码
首先,了解要移植的 C 模块(在 src/ 中查找 $ARGUMENTS.c 和 $ARGUMENTS.h):
- 阅读
src/中的.c和.h文件 - 确定头文件公开了哪些内容:
- 代码库的其他部分能否访问此模块中定义的数据结构的内部字段?
- 类型是否始终按值或按引用传递?是否两种方式都有?
- 对应的 Rust 类型能否通过 FFI 边界传递?
- 了解数据结构及其生命周期
- 确定此模块从其他模块导入的类型和函数:
- 确定这些类型是用 Rust 还是 C 实现的
- 如果这些类型是用 Rust 实现的,找出相关的 Rust crate
- 如果这些类型是用 C 实现的,了解是否适合先将它们移植到 Rust, 或者是否更适合通过 FFI 从 Rust 调用 C 实现
- 记录任何全局状态或 Redis 模块交互
- 确定
tests/下与此模块相关的测试
2. 制定移植计划
创建 $ARGUMENTS_plan.md 文件,概述移植模块的步骤和决策。
确定现阶段是否应修改 C 代码以简化移植过程。
例如:
- 添加 getter 和 setter,避免公开此模块中定义的数据结构的内部字段。
- 将模块拆分为更小、更易管理的部分。
3. 创建 Rust Crate
cd src/redisearch_rs
cargo new $ARGUMENTS --lib
4. 实现纯 Rust 逻辑
- 编写符合 Rust 惯用风格的代码
- 添加全面的测试
- 确保所有 C/C++ 测试都有对应的 Rust 测试
- 使用文档注释记录公共 API
- 对性能敏感的代码,使用
criterion创建微基准测试 - 在适当情况下,使用
proptest进行基于属性的测试 - 编写测试代码时,应像对待生产代码一样认真
5. 将 Rust API 与 C API 对比
- 对照头文件中的 C API,检查新 Rust 模块的公共 API
- 确保可通过添加适当的封装或适配器来弥合差异
- 如果发现无法在不重新设计的情况下弥合差异,请返回步骤 1
6. 创建 FFI 封装
创建一个 FFI crate,以便向 C 代码库公开新的 Rust 模块:
cd src/redisearch_rs/c_entrypoint
cargo new ${ARGUMENTS}_ffi --lib
FFI crate 应:
- 暴露
#[unsafe(no_mangle)] pub extern "C" fn函数 - 处理空指针和错误情况
- 安全地转换 C 和 Rust 类型
- 使用
// SAFETY:注释记录所有 unsafe 代码块
7. 接入 C 代码
- 删除 C 头文件及其实现
- 更新 C 代码库的其余部分,在原 C 头文件的使用处导入新的 Rust 头文件
Rust FFI crate 的 C 头文件会自动生成。导入时无需使用完整路径,
只需使用其名称(例如,对于 ${ARGUMENTS}_ffi,使用 #include $ARGUMENTS.h;)
8. 测试集成
./build.sh RUN_UNIT_TESTS # C/C++ unit tests
./build.sh RUN_PYTEST # Integration tests
示例:移植良好的模块
参见 src/redisearch_rs/trie_rs/,了解高质量示例:
- 纯 Rust 实现,文档全面
- 测试覆盖广泛
c_entrypoint/trie_ffi/中整洁的 FFI 边界
评论
支持 Markdown