C语言 使用wasmtime运行wasm文件时调用函数失败

3pvhb19x  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(108)

Mozilla分享了WASI以及如何使用Wasmtime在他们的blog post中运行.wasm文件。他们演示的编程语言是Rust

#[wasm_bindgen]
pub fn render(input: &str) -> String {
    let parser = Parser::new(input);
    let mut html_output = String::new();
    html::push_html(&mut html_output, parser);
    return html_output;
}

字符串
我想在 *。
我已经下载了wasi-libc,并试图用Clang构建一个'hello world'程序。
我在test.c中创建了两个函数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int foo1()
{
    printf("Hello foo1()\n");
    return 0;
}

int foo2(char* filename)
{
    printf("Hello foo2()\n");
    printf("filename is %s\n", filename);
    return 0;
}


用命令构建它:

clang --target=wasm32-wasi --sysroot=/mnt/d/code/wasi-libc/sysroot test.c -o test.wasm -nostartfiles -Wl,--no-entry,--export=foo1,--export=foo2


运行wasm文件以调用函数:

$ wasmtime test.wasm --invoke foo1
Hello foo1()
warning: using `--render` with a function that returns values is experimental and may break in the future
0

$ wasmtime test.wasm --invoke foo2 "hello"
warning: using `--render` with a function that takes arguments is experimental and may break in the future
error: failed to process main module `test.wasm`
    caused by: invalid digit found in string


我无法用输入参数调用函数。
Rust和C有什么区别?Rust是目前构建wasm lib文件的唯一方法吗?

00jrzges

00jrzges1#

不同之处在于Rust工具链对接口类型有实验性的支持,而不幸的是,C还不存在这种支持。render函数上面的#[wasm_bindgen]render转换为使用接口类型绑定导出的函数。

vmjh9lq9

vmjh9lq92#

由于Wasm的沙盒内存结构,它无法访问外部内存。您在这里传递的字符串存储在主机的内存中。对于Wasm,所有指针类型都表示为从其基址的偏移量,即i32。因此,即使您在这里传递字符串,Wasm内存仍然会在将其传递给foo2之前尝试将其转换为i32。然而,这里Wasm脚本无法实现这一点。您可以尝试使用Wasmer来运行它。您将得到一个更清晰的错误消息,如下所示:

error: failed to run `test.wasm`
  Can't convert `hello` into a i32

字符串
如果确实需要通过C向Wasm传递字符串,可以使用Wasm端提供的C API,具体做法是先使用Wasm端的malloc函数分配一块内存,然后将主机端的字符串复制到自己分配的内存中,最后将分配内存的起始地址作为参数传递给相应的函数。

相关问题