当前位置: 首页 > news >正文

如何完成一个简单的rust WebAssembly调用

1、安装wasm编译目标

rustup target add wasm32-unknown-unknown
wasm32-unknown-unknown 是 WebAssembly (Wasm) 的一个编译目标,表示一个独立于特定环境(如浏览器或Node.js)的 32 位 WebAssembly 二进制文件。它是 Rust 等语言编译成 WebAssembly 的基础,用于生成可在任何支持 Wasm 的环境中运行的代码。 - wasm32: 指示目标架构是 32 位 WebAssembly。
- unknown: 表示目标操作系统和 ABI(应用程序二进制接口)是未知的,因为 Wasm 是一种通用格式,它不依赖于特定的操作系统。
- 用途: 它是生成独立于特定环境的 WebAssembly 模块的基础。
- 扩展: 在 wasm-bindgen 等项目中,wasm32-unknown-unknown 是基础目标,其他特定环境的目标会基于它进行扩展,以添加与 JavaScript 或其他环境的绑定代码和加载逻辑。 

2、安装wasm-pack可执行工具

cargo install wasm-pack

3、以lib形式新建项目

cargo new wasm-demo --lib

4、在wasm-demo的toml文件加上

[package]
name = "wasm-demo"
version = "0.1.0"
edition = "2024"[lib]
crate-type = ["cdylib"][dependencies]
wasm-bindgen = "0.2.105"

解析: crate-type是什么

   crate-type = ["cdylib"] 是 Rust 项目中的一个配置,它告诉编译器将项目编译成一个动态库,该库可以被其他语言(如 C, C++)通过 FFI (Foreign Function Interface) 调用。这意味着生成的库不是一个独立的 Rust 可执行文件,而是供其他程序集成的共享库文件,例如生成 .so (Linux), .dylib (macOS) 或 .dll (Windows) 文件。 详细解释:
- [lib]: 这表示该配置是针对库 (lib) 的。在 Cargo.toml 文件中,[lib] 部分通常包含关于如何构建这个库的设置。
- crate-type: 这个键指定了 Rust crate 的类型。
- ["cdylib"]: 这是 crate-type 的一个值,表示创建的是一个 "C-compatible dynamic library"。
- c: 强调这是一个可以被 C 语言使用的动态库。
- dylib: 表示这是一个动态库文件,而不是静态库。
- 用途: 这种设置主要用于希望将 Rust 代码作为库提供给其他非 Rust 语言的项目使用,例如开发操作系统组件、游戏引擎、浏览器插件等。 
与其他库类型的区别
- rlib: 这是 Rust 自身的静态库格式,只能被其他 Rust 项目链接使用。
- staticlib: 创建一个可以在其他语言中作为静态库使用的库,它会被直接链接到目标程序中,而不是作为单独的动态共享库

5、lib.rs文件写上

use wasm_bindgen::prelude::*;#[wasm_bindgen]
pub fn add(left: u64, right: u64) -> u64 {left + right
}#[wasm_bindgen]
pub fn greet(name: &str) -> String {format!("Hello, {}!", name)
}#[wasm_bindgen]
pub fn sum_bytes(data: &[u8]) -> u32 {data.iter().map(|&b| b as u32).sum()
}#[wasm_bindgen]
pub fn make_data(size: usize) -> Vec<u8> {(0..size as u8).collect()
}#[cfg(test)]
mod tests {use super::*;#[test]fn it_works() {let result = add(2, 2);assert_eq!(result, 4);}#[test]fn greet_works() {let result = greet("World");assert_eq!(result, "Hello, World!");}#[test]fn sum_bytes_works() {let data = vec![1, 2, 3, 4, 5];let result = sum_bytes(&data);assert_eq!(result, 15);}#[test]fn make_data_works() {let size = 5;let result = make_data(size);assert_eq!(result, vec![0, 1, 2, 3, 4]);}
}

6、编译成wasm

  • 运行后可以看见一个pkg文件夹,里面有wasm、ts和js的后缀文件,这些就是可以在网页中直接使用的文件。
wasm-pack build --target web

7、调用

<!DOCTYPE html>
<html><body><button id="btn">add</button><button id="btn1">greet</button><button id="btn2">sum</button><button id="btn3">array</button><script type="module">import init, { add, greet,sum_bytes,make_data} from "./wasm-demo/pkg/wasm_demo.js";// 初始化 WASM 模块async function main() {await init(); }main();//   绑定按钮事件   document.getElementById("btn").onclick = () => {alert("ADD" + add(10n, 20n));};document.getElementById("btn1").onclick = () => {alert(greet("Rust"));};document.getElementById("btn2").onclick = () => {alert(sum_bytes(new Uint8Array([1,2,3,4,5])));};document.getElementById("btn3").onclick = () => {alert(make_data(5));};</script></body>
</html>

8、wasm里rust和js类型的对应问题

number:- i8	- i16	- i32- u8	- u16	- u32	- f32	- f64	
BigInt:- i64- u64
boolean:- bool
string:- char- &str- String
Array:- vec
TypedArray:- &[T]- Uint8Array = &[u8]- Int8Array = &[i8]- Uint16Array = &[u16]- Float32Array = &[f32]- Float64Array = &[f64]
  • 上面代码可以看见BigInt数字要加上n,不然报错。
  • 而最后的类型切片, 其实涉及共享内存的概念——Rust的数组数据存放在wasm的线性内存(WebAssembly.Memory)中,而 JS 的 Uint8Array 是这块内存的“视图”,也就是说Rust的&[u8]只是这块内存的“引用”,而JS的Uint8Array是通过 new Uint8Array(wasm.memory.buffer, offset, length)访问相同的内存。这期间wasm-bindgen完成了:
      -- 把 JS 数组拷贝进 wasm 内存;-- 传入内存偏移和长度;-- 调用 wasm 函数;-- 可能再把结果从 wasm 内存拷回 JS。
    
http://www.jsqmd.com/news/38683/

相关文章:

  • 焊接工业机器人节气装置
  • 详细介绍:考研408--组成原理--day1
  • 深入解析:海尔 Haier Master 智能家居网关安装 Home Assistant 实践指南
  • 枣庄西林瓶灌装轧盖机:SIP灭菌快,自动冷却高效
  • 【Nano Banana超详细教程】AI绘图神器Gemini 2.5实测:一键生成神图!
  • 已完成今日基础缩索大学习
  • 配置ElactisSearch跨域
  • 西林瓶粉末灌装机:塔城培训服务免费提供
  • Ubuntu设置中文智能拼音输入法
  • 一份用pyhon生成word/wps文档的代码2
  • 200粉粉福
  • 【chrome】chrome浏览器OptGuideOnDeviceModel模型占用磁盘空间的解决方法!
  • 这样的算作“全栈技术”吗?
  • 2025-11-12 aoao Round2 赛后总结
  • 商丘西林瓶灌装线:人员更替需再培训?费用明晰
  • vue3+ts实现页面滚动位置的保存及恢复
  • SAP屏幕增强自定义界面字段使用自定义搜索帮助方法
  • 南大-操作系统-绿导师原谅你了
  • 昌都西林瓶粉末灌装机:远程可控,手机电脑轻松操作
  • 深入解析:EI会议预订又又+1
  • 牛B, 我去,新手小白也能使用InfiniteTalk搭建属于自己的数字人啦 ,真的太简单啦!!!
  • QCombox判断是否包含某项
  • 植物大战僵尸2下载教程:延续经典塔防,体验全新时空冒险
  • 阳江西林瓶灌装加塞机:多品牌如何选?看这几点
  • JavaWeb05-Web基础
  • CF125E MST Company
  • Git分支合并
  • 西林瓶灌装机质
  • PG系列:Select查询一样会被阻塞
  • 物理光学中光束传输与变换的数值模拟研究