31|FFI:Rust如何和你的语言架起沟通桥梁?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Rust FFI(Foreign Function Interface)是如何与其他语言建立通信桥梁的?本文介绍了Rust与C/C++的互操作,以及如何使用bindgen工具生成Rust FFI代码。通过示例展示了如何调用C库,包括创建shim代码、生成Rust FFI代码、封装低层代码以提供更Rusty的接口。文章还提到了处理FFI的注意事项,包括处理数据结构差异、内存释放和错误处理。总的来说,Rust FFI能够方便地集成C库,为读者展示了Rust在处理FFI方面的便利性和贴心性。 此外,文章还介绍了Rust与Python、Node.js、Erlang/Elixir、C++、Kotlin/Swift等语言的互操作方式,以及uniffi工具的使用。通过使用uniffi,读者可以方便地生成各种语言的FFI代码,展示了Rust在多语言互操作方面的灵活性和便利性。 最后,文章提到了除了FFI外,还可以使用REST API、gRPC和protobuf等方式进行跨语言共享。并强调了Rust在提供底层支持时的安全性和高性能,以及在开发跨越多个端的公共库时的优势。 总的来说,本文全面介绍了Rust FFI与其他语言的互操作方式,展示了Rust在处理跨语言通信方面的优势和便利性。
《陈天 · Rust 编程第一课》,新⼈⾸单¥68
全部留言(8)
- 最新
- 精选
- 卷王之王你好,我想用c语言调用rust,rust代码中用到了tokio。tokio的main函数中有 #[tokio::main] 的标记。这种情况不知道怎么提供给c语言接口了。 #[tokio::main] async fn main() -> Result<()> { // Open a connection to the mini-redis address. let mut client = client::connect("127.0.0.1:6379").await?;
作者回复: 宏只不过是对 runtime 的包装。参见:https://docs.rs/tokio/latest/tokio/runtime/index.html
2022-01-152 - Marvichov私以为对FFI的理解, 重点还是对ABI的理解; C-ABI就像英语一样…不同母语的人可以通过英语交流…数据转换就相当于翻译的过程…中文 → 英文 → 法文; 目前很多机器翻译AI也是把target lang翻译成英语…英语有点像一个MIR了 ABI里面最重要的, 估计就是calling convention了: https://flint.cs.yale.edu/cs421/papers/x86-asm/asm.html; - 阅读 std::ffi 的文档,想想 Vec 如何传递给 C?再想想 HashMap 该如何传递?有必要传递一个 HashMap 到 C 那一侧么? 如果用std::ffi的话, 需要把Vec<T>转成Vec<u8>再转成CString…能不能传, 还有个关键是T必须要有C representation和bindings, 不然到了C里面, 也不知道怎么用T… HashMap没必要, 也需要做类似的serialization, 但是, 怎么做deserialization就没那么容易了; 毕竟从一个nul-terminated 的char*里面还原HashMap是不可能的 - 阅读 rocksdb 的代码,看看 Rust 如何提供 rocksDB 的绑定。 https://github.com/rust-rocksdb/rust-rocksdb/blob/master/librocksdb-sys/build.rs; librocksdb-sys提供C bindings → unsafe crate → 挺复杂的, bind了很多库… 整个rocksdb crate提供safe rust api;
作者回复: 对于 HashMap 这样的结构,我们只需要传一个简单的 wrapper,而不是尝试在两端去 serialize/deserialize。因为你用到的是它的功能,其实并不关心它数据存了些什么,怎么存储的。做 FFI 切忌过于纠结数据结构如何 mapping,大部分时候,我们需要的是另一侧提供的功能。所以,只要输入输出有合适的 mapping 或者 ser/de,具体另一侧怎么实现的,完全不要去关心。在我用 pyo3 封装 xunmi 时,给出了很好的示范。
2021-11-1421 - MarvichovQ: 有个小问题, 为啥bindings.h不需要以下这些header, 咋一build就自动添加这些header呢? 难道是ffi的scaffolding的代码需要? #include <cstdarg> #include <cstdint> #include <cstdlib> #include <ostream> #include <new> Q: Swift call rust FFI 代码的时候, 发生了什么呢? 我猜想是: `dlopen` 找到rust代码编译成的dylib, 然后用dlsym 找到函数 `math::hello`; `math_6c3d_hello` 封装好了这个流程. public func hello(name: String) -> String { let _retval = try! rustCall { math_6c3d_hello(name.lower(), $0) } return try! String.lift(_retval) } ... private func makeRustCall<T>(_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T, errorHandler: (RustBuffer) throws -> Error) throws -> T { var callStatus = RustCallStatus() let returnedVal = **callback(&callStatus)** // ... }
作者回复: 1. 对,自动生成的 2. 对
2021-11-141 - overheat"正常情况下应该创建另一个 crate 来撰写这样的接口",如果发布到crates.io上,“另一个crate”需要单独发布吗?也就是说在使用时会有两个dependences需要加入toml吗?(一个abc-sys,还有一个abc-interface)
作者回复: 需要单独发布,如果你是在不想单独发布,就需要通过在 dependency 里用 git 的方式引入
2021-11-232 - Marvichov> The ABI for C is platform-specific (OS, processor) - it covers issues such as register allocation and calling conventions, which are obviously specific to a particular processor. https://stackoverflow.com/questions/4489012/does-c-have-a-standard-abi 这样的话, 在之前评论里, 英语的那个类比就不恰当了...英语有很多dialect, 大家是可以用**标准**英语交流...和普通话一样的道理, 有个公认的标准... 那么问题来了, 既然C-abi并没有标准, 为什么大家喜欢选择它作为中间的bridge呢? 难道是因为它最简单通用, 没有标准也可以 (实现不用platform agonostic)?
作者回复: C ABI 是有标准的(主要就是寄存器和栈如何使用),只不过不同 CPU 和 OS 有不同的标准。比如 arm 哪个寄存器用作返回值和 x64/powerpc/mips 就不同,这非常正常。但在同一个 CPU/OS 下,C ABI 是一致的。而且所有系统的 library 都是用 C ABI,所以使用它做中间媒介再合适不过。
2021-11-16 - 罗杰如何在 build.rs 断点调试呢?
作者回复: 没有试过,需要找到 build binary 对应的 process,然后想办法 gdb attach 进去。这里有个讨论:https://www.reddit.com/r/rust/comments/72ip1h/attach_gdb_to_buildrs/
2021-11-08 - 沈畅thread 'main' panicked at 'Unable to find libclang: "the `libclang` shared library at /home/dev12/llvm/lib/libclang.so.9 could not be opened: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /home/dev12/llvm/lib/../lib/libc++abi.so.1)"', /home/dev12/.cargo/registry/src/mirrors.zte.com.cn-e61ca787596def60/bindgen-0.59.2/src/lib.rs:2144:31 这个问题大家遇见过吗?难道clang版本太低了?2022-09-17归属地:江苏11
- Edwin目前我们正在做3的事情2022-02-27