WebAssembly - Hello World

  • 简述

    在本章中,我们将用 C 编写一个简单的程序并将其转换为 .wasm 并在浏览器中执行相同的程序以获取文本“Hello World”。
    将使用将 C 程序转换为 .wasm 的 wasm 资源管理器工具,并将使用 .html 文件中的 .wasm。
    可在https://mbebenita.github.io/WasmExplorer/ 获得的 Wasm 资源管理器工具如下所示 -
    C代码
    我们将使用的 C 代码如下 -
    
    #include <stdio.h>
    char *c_hello() {
       return "Hello World"; 
    }
    
    使用 C 代码更新 wasm explorer 中的第一个块,如下所示 -
    更新第一个块
    单击编译按钮编译为 WASM 和 WAT 和 Firefox x86 Web 程序集,如下所示 -
    编译
    使用 DOWNLOAD 获取 .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步

    .wasm 代码必须使用ArrayBuffer转换为 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();
    
    现在,测试变量具有读取我们字符串的起点。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 中,所以字符串显示在浏览器上。
  • 输出

    输出如下所述 -
    你好世界