WebAssembly (Wasm) 与 JavaScript 字符串交互

server/2024/9/25 9:03:50/

随着WebAssembly(简称Wasm)技术的发展,越来越多的Web应用开始利用Wasm来提高性能。Wasm是一种在现代Web浏览器中运行的二进制格式,可以提供接近原生代码的速度。然而,Wasm和JavaScript之间进行数据交换时需要特别注意,尤其是对于字符串这种复杂类型的数据。

基础知识

在Wasm中,内存是通过线性内存(Linear Memory)来管理的,它是一个连续的字节数组。由于Wasm本身没有字符串类型,因此字符串必须以某种方式编码为字节序列后才能存储在线性内存中。通常,我们使用UTF-8编码来表示字符串。

JavaScript与Wasm之间的字符串交互涉及以下几个关键步骤:

  1. 从JS向Wasm传递字符串:将字符串转换为UTF-8编码,并将其写入Wasm的线性内存中。
  2. Wasm处理字符串:在Wasm中读取并处理这些字符串。
  3. 从Wasm向JS返回字符串:将处理后的字符串从线性内存中读出,并转换回JavaScript中的字符串。
示例代码

下面我们将通过一个简单的例子来演示如何实现上述过程。假设我们有一个Wasm模块,该模块包含一个函数to_uppercase,它可以接收一个字符串参数,对其进行某些处理(例如转换成大写),然后返回处理后的字符串。

wasm_15">Wasm 模块 (example.wasm)

首先,我们需要编写一个简单的Wasm模块。这里使用C语言作为示例:

#include <emscripten.h>
#include <string>
#include <cstring>extern "C" {EM_PORT_API const char* to_uppercase(const char* input) {std::string output = input;for (char &c : output) {c = toupper(c); // 转换为大写}// 为输出字符串分配内存char* result = (char*)malloc(output.size() + 1);strcpy(result, output.c_str());return result; // 返回大写字符串
}EM_PORT_API void free_string(const char* str) {free((void*)str); // 释放分配的内存
}}

编译上述C代码为Wasm模块(使用emcc命令):

emcc string.cpp -o string.js -s MODULARIZE=1 -s EXPORT_NAME="createModule" -s "EXPORTED_FUNCTIONS=['_to_uppercase', '_free_string','UTF8ToString','allocateUTF8']" -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']"

EXPORTED_FUNCTIONS里面是Wasm对js开放的函数,写在c里面用_做前缀导出,非c的,js的就是原来的样子,这类非c的函数有哪些可以在生成的string.js里面看,根据需要导出
举例:‘allocateUTF8’,‘UTF8ToString’,‘getValue’,‘intArrayFromString’,‘intArrayToString’,‘UTF8ArrayToString’,‘stringToUTF8Array’,‘stringToUTF8’,‘allocate’,‘ALLOC_NORMAL’
这将生成两个文件:string.jsstring.wasm。其中,string.js 是一个加载器,用于帮助加载和初始化Wasm模块。

JavaScript 调用

接下来,在JavaScript中调用这个Wasm函数:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebAssembly String Processing</title><script src="string.js"></script>
</head>
<body><h1>WebAssembly String Processing</h1><input type="text" id="inputString" placeholder="Enter string"><button id="convertButton">Convert to Uppercase</button><p id="result"></p><script>javascript">let moduleInstance;createModule().then(instance => {moduleInstance = instance;document.getElementById('convertButton').onclick = () => {const inputString = document.getElementById('inputString').value;// 调用 C++ 函数const upperPtr = moduleInstance._to_uppercase(moduleInstance.allocateUTF8(inputString));const upperString = moduleInstance.UTF8ToString(upperPtr);document.getElementById('result').innerText = `Uppercase: ${upperString}`;// 释放分配的内存moduleInstance._free_string(upperPtr);};});</script>
</body>
</html>

在这个例子中,我们使用了allocateUTF8UTF8ToString这两个辅助函数。allocateUTF8是将js字符串分配好空间,变成c的char指针,给到wasm访问,UTF8ToString则是将wasm的char指针变成js能用字符串。记住,wasm跟js的实际通讯只有数字,int,char这些。

总结

通过以上示例,我们可以看到在Wasm和JavaScript之间传递字符串并不是一件直接的事情,需要经过编码、解码以及内存管理的过程。不过,借助于Emscripten提供的工具和API,这一过程可以变得更加简单和高效。

希望这篇文章能帮助你更好地理解Wasm与JavaScript之间的字符串交互机制。如果你有任何疑问或建议,欢迎留言交流!


http://www.ppmy.cn/server/121745.html

相关文章

随笔 程序运行的基本原理

程序是如何运行&#xff0c;又是如何崩溃的&#xff1f; 正如标题所言&#xff0c;今天我们来聊聊程序是如何执行的&#xff1f;以及又是如何崩溃的&#xff1f;我们哼哧哼哧写的代码并不是程序&#xff0c;本质上不过是一个文本文件。即便我们将我们写的代码通过编译生成的可…

NPM如何切换淘宝镜像进行加速

什么是淘宝镜像NPM&#xff1f; 淘宝镜像NPM和官方NPM的主要区别在于服务器的地理位置和网络访问速度。淘宝镜像NPM是由淘宝团队维护的一个npm镜像源&#xff0c;主要服务于中国大陆用户&#xff0c;提供了一个国内的npm镜像源&#xff0c;地址为 https://registry.npmmirror.…

MQ的简单梳理

MQ 作用场景消息可靠性消息顺序性消息堆积 作用 集成MQ后&#xff0c;同步调用变成了向MQ发消息&#xff0c;对目标服务的调用&#xff0c;由同步变成了异步&#xff0c;实现了服务间的解耦。得益于这种异步&#xff0c;方法调用被封装成消息存放在MQ中&#xff0c;下游目标服…

《AI办公类工具PPT系列之六——轻竹办公》

一.简介 官网:轻竹办公PPT|AI自动生成PPT_Word文档转PPT_海量PPT模版_在线PPT制作_智能生成PPT_一键生成PPT_智能生成演讲稿_AIPPT 轻竹办公PPT是一款结合人工智能技术专为PPT制作而设计的办公工具,旨在简化和加速PPT的创建过程。用户只需输入标题,AI便会在几十秒内生成所…

学习一下怎么用git

目录 初始化操作 设置名字&#xff1a; 设置邮箱: 查询状态 初始化本地仓库 清空git bush控制台 git的三个区域 文件提交 将会文件提交到暂存区 暂存指定文件 暂存所有改动文件 查看暂存区里面的文件 将文件提交到版本库 git文件状态查看 ​编辑 暂存区的相关指令…

SpringSecurity

目录 认证授权概念 1.1 什么是认证 1.2 什么是授权 权限数据类型 常见的认证方式 一:Cookie-Session 二: jwt令牌无状态认证 JWT 一.JWT简介 二.JWT组成 三.JWT使用 1.导入jwt依赖 2.生成JWT令牌 3.JWT令牌校验 四.JWT在前端保存方案 SpringSecurity SpringSecurity…

CSS——网格布局(display: grid)之下篇

CSS——网格布局&#xff08;display: grid&#xff09;之下篇 前面我们介绍了网格布局的基础的创建以及一些比较基础的属性&#xff0c;下面我们将介绍网格布局的剩余部分&#xff0c;还将结合实例来进行细致的讲解&#xff08;图文并茂&#xff0c;生动形象有内涵&#xff0…

云栖实录 | 阿里云 OpenLake 解决方案重磅发布:多模态数据统一纳管、引擎平权联合计算、数据共享统一读写

新一轮人工智能浪潮正在重塑世界&#xff0c;以生成式 AI 为代表的技术快速应用&#xff0c;推动了数据与智能的深化融合&#xff0c;同时也给数据基础设施带来了全新的变革与挑战。面向 AI 时代的数据基础设施如何构建&#xff1f;底层数据平台架构在 AI 时代如何演进&#xf…