• 卷王之王
    2022-01-15
    你好,我想用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

    
    2
  • Marvichov
    2021-11-14
    私以为对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 时,给出了很好的示范。

    共 2 条评论
    1
  • Marvichov
    2021-11-14
    Q: 有个小问题, 为啥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. 对

    
    1
  • overheat
    2021-11-23
    "正常情况下应该创建另一个 crate 来撰写这样的接口",如果发布到crates.io上,“另一个crate”需要单独发布吗?也就是说在使用时会有两个dependences需要加入toml吗?(一个abc-sys,还有一个abc-interface)

    作者回复: 需要单独发布,如果你是在不想单独发布,就需要通过在 dependency 里用 git 的方式引入

    共 2 条评论
    
  • Marvichov
    2021-11-16
    > 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-08
    如何在 build.rs 断点调试呢?

    作者回复: 没有试过,需要找到 build binary 对应的 process,然后想办法 gdb attach 进去。这里有个讨论:https://www.reddit.com/r/rust/comments/72ip1h/attach_gdb_to_buildrs/

    
    
  • 沈畅
    2022-09-17 来自江苏
    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版本太低了?
    
    
  • Edwin
    2022-02-27
    目前我们正在做3的事情
    
    