Rust WebAssembly运行时Wasmtime C API实现库wasmtime-c-api-impl的使用,支持高效WASM模块加载与跨语言交互

Rust WebAssembly运行时Wasmtime C API实现库wasmtime-c-api-impl的使用,支持高效WASM模块加载与跨语言交互

API文档

在C/C++项目中使用

使用预构建的静态或动态库

Wasmtime提供了各种架构和操作系统的预构建二进制文件,包括静态库、动态库和头文件。

从源码构建Wasmtime C/C++ API

要使用Wasmtime的C/C++ API,需要安装CMake和Rust工具链。

从Wasmtime仓库根目录运行以下命令:

$ cmake -S crates/c-api -B target/c-api --install-prefix "$(pwd)/artifacts"
$ cmake --build target/c-api
$ cmake --install target/c-api

构建完成后会生成以下文件:

  • artifacts/lib/libwasmtime.{a,lib}: 静态库
  • artifacts/lib/libwasmtime.{so,dylib,dll}: 动态库
  • artifacts/include/**.{h,hh}: 头文件

在Rust项目中使用

如果您的Rust crate需要绑定使用Wasmtime的C/C++库,可以通过Cargo链接Wasmtime C API。

  1. Cargo.toml中添加依赖:
[dependencies]
wasmtime-c-api = { version = "16.0.0", package = "wasmtime-c-api-impl" }
  1. build.rs中添加Wasmtime C头文件路径:
fn main() {
    let mut cfg = cc::Build::new();

    // 添加Wasmtime头文件路径
    cfg
        .include(std::env::var("DEP_WASMTIME_C_API_INCLUDE").unwrap());

    // 编译您的C代码
    cfg
        .file("src/your_c_code.c")
        .compile("your_library");
}

完整示例

下面是一个完整的Rust项目示例,演示如何使用wasmtime-c-api-impl加载和运行WASM模块:

首先在Cargo.toml中添加依赖:

[dependencies]
wasmtime-c-api = { version = "16.0.0", package = "wasmtime-c-api-impl" }

然后创建一个Rust项目:

use wasmtime_c_api::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化Wasmtime引擎
    let engine = wasm_engine_new();
    
    // 创建存储
    let store = wasm_store_new(engine, std::ptr::null_mut());
    
    // 加载WASM模块
    let wasm = include_bytes!("example.wasm");
    let module = wasm_module_new(store, wasm.as_ptr() as *const u8, wasm.len())?;
    
    // 创建实例
    let instance = wasm_instance_new(store, module, std::ptr::null_mut(), 0, std::ptr::null_mut())?;
    
    // 获取导出函数
    let exports = wasm_instance_exports(instance);
    let func = wasm_extern_as_func(wasm_extern_vec_get(exports, 0));
    
    // 调用WASM函数
    let params = [wasm_val_i32(5)];
    let mut results = [wasm_val_uninit()];
    wasm_func_call(func, params.as_ptr(), results.as_mut_ptr())?;
    
    // 获取结果
    let result = unsafe { results[0].of.i32 };
    println!("WASM函数返回: {}", result);
    
    // 清理资源
    wasm_instance_delete(instance);
    wasm_module_delete(module);
    wasm_store_delete(store);
    wasm_engine_delete(engine);
    
    Ok(())
}

这个示例展示了如何:

  1. 初始化Wasmtime引擎
  2. 加载WASM模块
  3. 创建实例
  4. 调用WASM函数
  5. 获取返回值
  6. 清理资源

通过wasmtime-c-api-impl,您可以轻松地在Rust项目中集成Wasmtime的C API功能,实现高效的WASM模块加载和跨语言交互。


1 回复

Rust WebAssembly运行时Wasmtime C API实现库wasmtime-c-api-impl使用指南

完整示例Demo

下面是一个完整的Rust示例,展示如何使用wasmtime-c-api-impl加载WASM模块并调用其中的函数:

use wasmtime_c_api_impl::{
    wasm_engine_new, wasm_store_new, wasm_byte_vec_new, wasm_module_new,
    wasm_instance_new, wasm_instance_exports, wasm_extern_as_func,
    wasm_func_call, wasm_val_t, wasm_valkind_enum,
    wasm_module_delete, wasm_byte_vec_delete, wasm_instance_delete,
    wasm_store_delete, wasm_engine_delete
};

fn main() {
    // 1. 初始化引擎和存储
    unsafe {
        let engine = wasm_engine_new();
        let store = wasm_store_new(engine);
        
        // 2. 加载和编译WASM模块
        // 示例WASM模块(一个简单的加法函数)
        let wasm_bytes: Vec<u8> = vec![
            0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 
            // ... 实际的WASM字节码
        ];
        
        let mut binary = wasm_byte_vec_new(wasm_bytes.len(), wasm_bytes.as_ptr() as *mut _);
        let module = wasm_module_new(store, &binary);
        
        // 3. 创建实例并调用函数
        let instance = wasm_instance_new(store, module, std::ptr::null(), std::ptr::null_mut());
        
        // 获取导出函数
        let exports = wasm_instance_exports(instance);
        let func = wasm_extern_as_func(*exports.offset(0)); // 假设第一个导出是add函数
        
        // 准备参数和结果
        let mut params = [
            wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 5 } },
            wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 7 } }
        ];
        let mut results = [wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 0 } }];
        
        // 调用函数
        if wasm_func_call(func, params.as_mut_ptr(), results.as_mut_ptr()).is_null() {
            println!("函数调用成功,结果: {}", results[0].of.i32);
        } else {
            println!("函数调用失败");
        }
        
        // 清理资源
        wasm_instance_delete(instance);
        wasm_module_delete(module);
        wasm_byte_vec_delete(&mut binary);
        wasm_store_delete(store);
        wasm_engine_delete(engine);
    }
}

C语言调用完整示例

#include <stdio.h>
#include <wasm.h>
#include <wasmtime.h>

int main() {
    // 初始化引擎和存储
    wasm_engine_t* engine = wasm_engine_new();
    wasm_store_t* store = wasm_store_new(engine);
    
    // 加载WASM模块
    FILE* file = fopen("add.wasm", "rb");
    if (!file) {
        printf("无法打开WASM文件\n");
        return 1;
    }
    
    fseek(file, 0, SEEK_END);
    size_t file_size = ftell(file);
    fseek(file, 0, SEEK_SET);
    
    wasm_byte_vec_t wasm;
    wasm_byte_vec_new_uninitialized(&wasm, file_size);
    if (fread(wasm.data, file_size, 1, file) != 1) {
        printf("读取WASM文件失败\n");
        fclose(file);
        return 1;
    }
    fclose(file);
    
    // 编译模块
    wasm_module_t* module = wasm_module_new(store, &wasm);
    if (!module) {
        printf("编译WASM模块失败\n");
        wasm_byte_vec_delete(&wasm);
        wasm_store_delete(store);
        wasm_engine_delete(engine);
        return 1;
    }
    
    // 创建实例
    wasm_instance_t* instance = wasm_instance_new(store, module, NULL, NULL);
    if (!instance) {
        printf("创建实例失败\n");
        wasm_module_delete(module);
        wasm_byte_vec_delete(&wasm);
        wasm_store_delete(store);
        wasm_engine_delete(engine);
        return 1;
    }
    
    // 获取导出函数
    wasm_extern_vec_t exports;
    wasm_instance_exports(instance, &exports);
    
    if (exports.size == 0) {
        printf("没有找到导出函数\n");
        wasm_instance_delete(instance);
        wasm_module_delete(module);
        wasm_byte_vec_delete(&wasm);
        wasm_store_delete(store);
        wasm_engine_delete(engine);
        return 1;
    }
    
    wasm_func_t* func = wasm_extern_as_func(exports.data[0]);
    if (!func) {
        printf("第一个导出不是函数\n");
        wasm_instance_delete(instance);
        wasm_module_delete(module);
        wasm_byte_vec_delete(&wasm);
        wasm_store_delete(store);
        wasm_engine_delete(engine);
        return 1;
    }
    
    // 准备参数和结果
    wasm_val_t params[2] = { WASM_I32_VAL(3), WASM_I32_VAL(4) };
    wasm_val_t results[1];
    
    // 调用函数
    if (wasm_func_call(func, params, results)) {
        printf("函数调用失败\n");
    } else {
        printf("3 + 4 = %d\n", results[0].of.i32);
    }
    
    // 清理资源
    wasm_instance_delete(instance);
    wasm_module_delete(module);
    wasm_byte_vec_delete(&wasm);
    wasm_store_delete(store);
    wasm_engine_delete(engine);
    
    return 0;
}

高级功能完整示例

use wasmtime_c_api_impl::{
    wasm_config_new, wasm_engine_new_with_config, wasmtime_config_debug_info_set,
    wasmtime_config_parallel_compilation_set, wasm_store_new, wasm_byte_vec_new,
    wasm_module_new, wasm_instance_new, wasm_instance_exports, wasm_extern_as_func,
    wasm_func_call, wasm_val_t, wasm_valkind_enum, wasm_functype_new, wasm_func_new,
    wasm_module_delete, wasm_byte_vec_delete, wasm_instance_delete, wasm_store_delete,
    wasm_engine_delete
};

unsafe {
    // 1. 配置引擎
    let config = wasm_config_new();
    wasmtime_config_debug_info_set(config, true); // 启用调试信息
    wasmtime_config_parallel_compilation_set(config, true); // 启用并行编译
    
    let engine = wasm_engine_new_with_config(config);
    let store = wasm_store_new(engine);
    
    // 2. 加载模块
    let wasm_bytes = wat::parse_str("
        (module
            (func $add (param i32 i32) (result i32)
                local.get 0
                local.get 1
                i32.add)
            (export \"add\" (func $add))
        )
    ").unwrap();
    
    let mut binary = wasm_byte_vec_new(wasm_bytes.len(), wasm_bytes.as_ptr() as *mut _);
    let module = wasm_module_new(store, &binary);
    
    // 3. 链接自定义主机函数
    extern "C" fn host_multiply(
        args: *const wasm_val_t,
        results: *mut wasm_val_t,
    ) -> *mut std::ffi::c_void {
        let a = unsafe { (*args.offset(0)).of.i32 };
        let b = unsafe { (*args.offset(1)).of.i32 };
        unsafe { (*results.offset(0)).of.i32 = a * b };
        std::ptr::null_mut()
    }
    
    let mut params = [wasm_valkind_enum::WASM_I32, wasm_valkind_enum::WASM_I32];
    let mut results = [wasm_valkind_enum::WASM_I32];
    let type_ = wasm_functype_new(
        params.as_mut_ptr(), params.len(),
        results.as_mut_ptr(), results.len()
    );
    
    let host_func = wasm_func_new(store, type_, host_multiply);
    
    // 4. 创建实例并调用函数
    let instance = wasm_instance_new(store, module, std::ptr::null(), std::ptr::null_mut());
    let exports = wasm_instance_exports(instance);
    let add_func = wasm_extern_as_func(*exports.offset(0));
    
    let mut add_params = [
        wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 6 } },
        wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 7 } }
    ];
    let mut add_results = [wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 0 } }];
    
    if wasm_func_call(add_func, add_params.as_mut_ptr(), add_results.as_mut_ptr()).is_null() {
        println!("6 + 7 = {}", add_results[0].of.i32);
    }
    
    // 调用主机函数
    let mut multiply_params = [
        wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 6 } },
        wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 7 } }
    ];
    let mut multiply_results = [wasm_val_t { kind: wasm_valkind_enum::WASM_I32, of: wasm_val_t__bindgen_ty_1 { i32: 0 } }];
    
    if wasm_func_call(host_func, multiply_params.as_mut_ptr(), multiply_results.as_mut_ptr()).is_null() {
        println!("6 * 7 = {}", multiply_results[0].of.i32);
    }
    
    // 清理资源
    wasm_instance_delete(instance);
    wasm_module_delete(module);
    wasm_byte_vec_delete(&mut binary);
    wasm_store_delete(store);
    wasm_engine_delete(engine);
}

这些完整示例展示了wasmtime-c-api-impl库的主要功能,包括基本使用、跨语言调用和高级功能配置。使用时请根据实际需求调整代码,并注意资源管理和线程安全等问题。

回到顶部