rust FFI 是rust与其他语言互调的桥梁,通过FFI rust 可以有效继承 C 语言的历史资产。本期通过几个例子来聊聊rust与 C 语言交互的具体步骤。
场景一 调用C代码
创建工程
Cargo.toml 配置
编写一个简单的c程序sample.c
main.rs
build.rs
代码目录树
场景二 使用bindgen 通过头文件绑定c语言动态链接库
修改Cargo.toml,新增bindgen依赖
新增 sample.h 头文件
新增 wrapper.h 头文件
wrapper.h 文件将包括所有各种头文件,这些头文件包含我们想要绑定的结构和函数的声明
改写build.rs
编译 sample.c 生成动态链接库sample.so;通过bindgen生成rust binding c 的代码并输出到 bindings 目录
修改main.rs
include 宏引入sample 动态链接库的binding。以前我们自己手写的C函数绑定就不需要了,看看bindings/sample_bindings.rs 的内容与我们手写的函数绑定是等效的
代码目录树
ffi_sample 工程的完整代码:https://github.com/jiashiwen/wenpanrust/tree/main/ffi_sample,读者可以clone https://github.com/jiashiwen/wenpanrust,直接运行即可
场景三 封装一个c编写的库
secp256k1是一个椭圆曲线计算的 clib,这玩意儿在密码学和隐私计算方面的常用算法,下面我们从工程方面看看封装secp256k1如何操作
cargo.toml
git 引入 submodule
工程下新建bindings目录用来存放绑定文件,该目录与src平级
wrapper.h
build.rs
cargo build 通过
编写测试 lib.rs
运行测试 cargo test 报错
报错显示找不到编译 secp256k1 相对应的库。
手动编译secp256k1
编译完成后,测试通过
其实 secp256k1 有对应的 [rust wrapper](https://github.com/rust-bitcoin/rust-secp256k1),我们这里只是展示一下封装的过程。
wrapper_secp256k1 工程的完整代码:https://github.com/jiashiwen/wenpanrust/tree/main/wrapper_secp256k1,有兴趣的朋友可以clone https://github.com/jiashiwen/wenpanrust。通过以下操作查看运行结果:
clone 项目
update submodule
编译 secp256k1
run test
参考资料:
[1] Rust FFI (C vs Rust)学习杂记.pdf:https://github.com/yujinliang/my_writing/blob/master/Rust%20FFI%20(C%20vs%20Rust)%E5%AD%A6%E4%B9%A0%E6%9D%82%E8%AE%B0.pdf
[2] bindgen官方文档:https://rust-lang.github.io/rust-bindgen/introduction.html
[3]Rust FFI 编程 - bindgen 使用示例:https://rustcc.cn/article?id=9219a366-84d3-49c8-b957-dfbade1257fc
领取专属 10元无门槛券
私享最新 技术干货