编译将 C++ 调用到 WASM 的 Rust

5 c++ ffi rust webassembly rust-wasm

我发现了这个How do I use a C library in a Rust library generated to WebAssembly? ,但这依赖于 wasm-merge,该功能已停止使用。我的问题如下,我有一些 C++ 代码,我想从 Rust 调用它们,以便可以选择将生成的包编译为在移动应用程序中使用的本机代码或在 Node.js 中使用的 WebAssembly。目前,我有以下设置:

libTest.cpp

extern "C"{
    int test_function(int i){
        return i;
    }
}
Run Code Online (Sandbox Code Playgroud)

库文件

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
}    
Run Code Online (Sandbox Code Playgroud)

构建.rs

fn main() {
    cc::Build::new()
        .cpp(true)
        .file("libTest.cpp")
        .compile("libTest.a");
}
Run Code Online (Sandbox Code Playgroud)

当使用简单的编译为本机代码时,它可以编译并工作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++
Run Code Online (Sandbox Code Playgroud)

这是解决此问题的正确方法吗?如果是,我该如何解决上述错误?如果没有,我如何最好地从 Rust 调用 C++ 并将其编译为 wasm?

Cae*_*sar 2

(这并不是一个完整的答案,但对于评论来说太长了。)

\n

我可以编译你的例子

\n
cc::Build::new()\n  .archiver("llvm-ar") // Takes care of "archive has no index" - emar might be an alternative\n  .cpp_link_stdlib(None) // Takes care of "unable to find library -lstdc++"\n  \xe2\x80\xa6 // rest of your flags\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

理论上你可以给 C++ 编译器一个完整的 stdlib 来使用.flag("--sysroot=/usr/share/wasi-sysroot/")(如果你安装了 wasi-sdk 或 wasi-libc++),但是

\n
    \n
  • 我不确定如何最好地解释此文件夹通常安装位置的差异(也许像这样
  • \n
  • 我认为你还必须在链接时传递这个标志,但我不知道如何(虽然它似乎没有工作)
  • \n
  • 它将针对 wasi,并且对于您想要的任何基于 Bindgen 的环境可能没有用。
  • \n
\n