我已经找到了这个How do I use a C library in a Rust library compiled to WebAssembly?,但这依赖于wasm-merge,它一直是discontinued.我的问题是,我有一些C++代码,我想从Rust调用它们,以便能够 Select 将生成的包编译为本地代码,以便在移动应用程序中使用,或者编译为WebAssembly,以便在Node.js中使用.目前,我有以下设置:

LibTest.cpp

extern "C"{
    int test_function(int i){
        return i;
    }
}

Lib.rs

use wasm_bindgen::prelude::*;

#[link(name = "Test")]
extern "C"{
    pub fn test_function(i: i32) -> i32 ;
}

#[wasm_bindgen]
pub fn test_function_js(i : i32) -> i32{
    let res = unsafe{test_function(i)};
    res
}    

Build.rs

fn main() {
    cc::Build::new()
        .cpp(true)
        .file("LibTest.cpp")
        .compile("libTest.a");
}

这在使用简单的cargo build编译为本机代码时可以编译并运行,但不适用于构建为wasm的代码,我使用的是cargo build --target wasm32-unknown-unknown.在那里我得到了两个错误

  = note: rust-lld: error: /[path to my project]/target/wasm32-unknown-unknown/debug/build/rustCpp-cc5e129d4ee03598/out/libTest.a: archive has no index; run ranlib to add one
          rust-lld: error: unable to find library -lstdc++

这是正确的方法吗?如果是,我如何解决上面的错误?如果不是,那么我应该如何从Rust调用C++并将其编译成WASM呢?

推荐答案

(这不是一个完整的答案,但太长了,不能发表 comments .)

我可以用以下命令编译您的示例

cc::Build::new()
  .archiver("llvm-ar") // Takes care of "archive has no index" - emar might be an alternative
  .cpp_link_stdlib(None) // Takes care of "unable to find library -lstdc++"
  … // rest of your flags

但我不确定生成的二进制文件对您是否有用.特别是,当在调试模式下编译时,它包含WASI导入,如果您开始使用任何有趣的函数(例如sin),您可能会收到链接器错误.

从理论上讲,您可以通过.flag("--sysroot=/usr/share/wasi-sysroot/")为C++编译器提供一个完整的stdlib(如果您已经安装了wasi-sdk或wasi-libc++),但是

  • 我不确定如何最好地解释此文件夹通常安装位置的不同(可能类似于this)
  • 我认为你也必须在链接时传递这个标志,但我不知道如何传递(尽管它似乎在没有的情况下也可以)
  • 这将以WASI为目标,并且对于您所考虑的任何基于绑定的环境可能都没有用处.

Rust相关问答推荐

Rust kill std::processs::child

为什么复印是豆荚的一个重要特征?

如何装箱生命周期相关联的两个对象?

抽象RUST中的可变/不可变引用

在Rust中宏的表达式中提取对象

这是不是在不造成嵌套的情况下从枚举中取出想要的变体的惯用方法?

变量需要parse()中的显式类型

如何将生存期参数添加到框<>;具有dyn类型别名

需要哪些编译器优化来优化此递归调用?

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

unwrap 选项类型出现错误:无法移出共享引用后面的*foo

Rust中的位移操作对范围有什么影响?

LinkedList::drain_filter::drop 中 DropGuard 的作用是什么?

改变不实现克隆的 dioxus UseState struct

Rust 中的通用 From 实现

为什么可以从闭包中返回私有 struct

TinyVec 如何与 Vec 大小相同?

Rust 为什么 (u32, u32) 的枚举变体的大小小于 (u64)?

如何迭代调用可能会失败的函数?操作员?

在 Rust 中组合特征的不同方法是否等效?