- WebAssembly 教程
- WebAssembly - 首页
- WebAssembly - 概述
- WebAssembly - 简介
- WebAssembly - WASM
- WebAssembly - 安装
- WebAssembly - 编译到 WASM 的工具
- WebAssembly - 程序结构
- WebAssembly - Javascript
- WebAssembly - Javascript API
- WebAssembly - 在 Firefox 中调试 WASM
- WebAssembly - “Hello World”
- WebAssembly - 模块
- WebAssembly - 验证
- WebAssembly - 文本格式
- WebAssembly - 将 WAT 转换为 WASM
- WebAssembly - 动态链接
- WebAssembly - 安全性
- WebAssembly - 使用 C 语言
- WebAssembly - 使用 C++
- WebAssembly - 使用 Rust
- WebAssembly - 使用 Go
- WebAssembly - 使用 Nodejs
- WebAssembly - 示例
- WebAssembly 有用资源
- WebAssembly - 快速指南
- WebAssembly - 有用资源
- WebAssembly - 讨论
WebAssembly - "Hello World"
本章我们将编写一个简单的 C 程序,将其转换为 .wasm 文件,并在浏览器中执行该文件,以获取文本“Hello World”。
我们将使用 wasm explorer 工具将 C 程序转换为 .wasm,并在我们的 .html 文件中使用该 .wasm 文件。
Wasm explorer 工具位于 https://mbebenita.github.io/WasmExplorer/,如下所示:
我们将使用的 C 代码如下:
#include <stdio.h> char *c_hello() { return "Hello World"; }
使用以下 C 代码更新 wasm explorer 中的第一个代码块:
点击“编译”按钮,编译到 WASM、WAT 和 Firefox x86 WebAssembly,如下所示:
使用“下载”按钮获取 .wasm 文件,并将其保存为 **firstprog.wasm**。
创建一个名为 firstprog.html 的 .html 文件,如下所示:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>WebAssembly Hello World</title> </head> <body> <div id="textcontent"></div> <script type="text/javascript"> //Your code from webassembly here </script> </body> </html>
现在让我们使用 firstprog.wasm 从 C 函数 c_hello() 读取 helloworld。
步骤 1
使用 fetch() api 读取 firstprog.wasm 代码。
步骤 2
使用 **ArrayBuffer** 将 .wasm 代码转换为 ArrayBuffer。ArrayBuffer 对象将返回一个固定长度的二进制数据缓冲区。
目前的代码如下:
<script type="text/javascript"> fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer()) </script>
步骤 3
使用 **WebAssembly.compile(buffer)** 函数将 ArrayBuffer 中的字节编译成模块。
代码如下:
<script type="text/javascript"> fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer()) .then(mod => WebAssembly.compile(mod)) </script>
步骤 4
要获取模块,我们必须调用 webassembly.instance 构造函数,如下所示:
<script type="text/javascript"> fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer()) .then(mod => WebAssembly.compile(mod)) .then(module => {return new WebAssembly.Instance(module) }) </script>
步骤 5
现在让我们在浏览器中查看实例的详细信息。
<script type="text/javascript"> fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer()) .then(mod => WebAssembly.compile(mod)) .then(module => { return new WebAssembly.Instance(module) }) .then(instance => { console.log(instance); }); </script>
console.log 的详细信息如下所示:
要从函数 c_hello() 获取字符串“Hello World”,我们需要在 javascript 中添加一些代码。
首先,获取内存缓冲区详细信息,如下所示:
let buffer = instance.exports.memory.buffer;;
缓冲区值必须转换为类型化数组,以便我们可以从中读取值。缓冲区中包含字符串 Hello World。
要转换为类型化数组,请调用 Uint8Array 构造函数,如下所示:
let buffer = new Uint8Array(instance.exports.memory.buffer);
现在,我们可以在 for 循环中从缓冲区读取值。
现在让我们通过调用我们编写的函数来获取读取缓冲区的起始点,如下所示:
let test = instance.exports.c_hello();
现在,test 变量具有读取字符串的起始点。WebAssembly 没有字符串值,所有内容都存储为整数。
因此,当我们从缓冲区读取值时,它们将是整数值,我们需要使用 javascript 中的 fromCharCode() 将其转换为字符串。
代码如下:
let mytext = ""; for (let i=test; buffer[i]; i++){ mytext += String.fromCharCode(buffer[i]); }
现在,当您在控制台中输出 mytext 时,您应该会看到字符串“Hello World”。
示例
完整的代码如下:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>WebAssembly Add Function</title> <style> div { font-size : 30px; text-align : center; color:orange; } </style> </head> <body> <div id="textcontent"></div> <script> fetch("firstprog.wasm") .then(bytes => bytes.arrayBuffer()) .then(mod => WebAssembly.compile(mod)) .then(module => {return new WebAssembly.Instance(module)}) .then(instance => { console.log(instance); let buffer = new Uint8Array(instance.exports.memory.buffer); let test = instance.exports.c_hello(); let mytext = ""; for (let i=test; buffer[i]; i++) { mytext += String.fromCharCode(buffer[i]); } console.log(mytext); document.getElementById("textcontent").innerHTML = mytext; }); </script> </body> </html>
我们添加了一个 div,并将内容添加到该 div 中,因此字符串将显示在浏览器上。
输出
输出如下所示: