WebAssembly学习笔记(一)

WebAssembly学习笔记(一)

编译和导入wasm模块

用Emscripten编译C/C++并使用HTML模板

让Emscripten生成WebAssembly模块、JavaScript plubming文件, 以及HTML模板文件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LK77Cj5N-1670298706899)(/img/webassembly/0101.png)]

  • 创建一个用于存放文件的目录: WebAssembly\Chapter 3\3.4 html_template\。

  • 创建C或C++代码。

    • 创建一个名为 calculate_primes.c 的文件。要做的第一件事是包含C标准库、 C标准输入和输出,以及Emscripten库的头文件。

    • #include <stdlib.h>

      #include <stdio.h>

      #include <emscripten.h>

  • 将C代码编译为WebAssembly模块。

    • 进入目录WebAssembly\Chapter 3\3.4 html_template\,打开一个控制台窗口,然后定位到这个目录。
    • 运行以下命令可以生成WebAssembly模块、JavaScript plumbing文件和一个HTML模板。
      • emcc calculate_primes.c -o html_template.html
  • 在Web浏览器中打开HTML文件查看结果。

    • Emscripten创建的HTML文件会将任何来自模块的printf输出定向到一个文本框,这样不需要打开浏览器开发者工具,就可以在页面上看到输出。

用Emscripten生成JavaScript plumbing代码

让Emscripten生成WebAssembly模块和JavaScript plumbing文件。修改一个HTML文件或者创建一个新文件,以引用生成的 JavaScript文件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rOC1UpCs-1670298706900)(/img/webassembly/0102.png)]

  • 创建一个用于存放文件的目录: WebAssembly\Chapter 3\3.5 js_plumbing\ 。

  • 创建C或C++代码。

  • 将C代码编译为WebAssembly模块。

    • 进入目录 WebAssembly\Chapter 3\3.5 js_plumbing\,打开一个控制台窗口,然后定位到这个目录。

    • 运行以下命令,让Emscripten创建WebAssembly 模块和JavaScript文件。

      • emcc calculate_primes.c -o js_plumbing.js

  • 修改一个HTML文件或者创建一个新文件,以引用生成的 JavaScript文件。

    • ←---- 这个JavaScript文件会处理WebAssembly模块的加载和实例化
  • 在Web浏览器中打开HTML文件查看结果。

用Emscripten只生成WebAssembly文件

让Emscripten只生成WebAssembly模块。 然后创建必要的 HTML和JavaScript代码,以下载和实例化模块。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ar1LanN8-1670298706900)(/img/webassembly/0103.png)]

  • 创建一个用于存放文件的目录:WebAssembly\Chapter 3\3.6 side_module\。

  • 是创建C/C++代码。

  • 让Emscripten只生成WebAssembly文件。

    • 含优化标记-O1,如果没有指定优化标记,则Emscripten会使用默认的-O0(大写字母O和数字0),这表示不执行任何优化。

    • 需要将函数Increment指定为导出函数,这样它才能够被JavaScript代码调用。为了向Emscripten编译器指示这一点,可以在命令行参数-s EXPORTED_FUNCTIONS中包含这个函数名。生成WebAssembly文件时, Emscripten会在这个函数前添加一个下划线字符,因此将函数名包含到导 出数组时,需要包含下划线字符:_Increment。

    • emcc side_module.c -s SIDE_MODULE=2 -O1

      ➥ -s EXPORTED_FUNCTIONS=[‘_Increment’] -o side_module.wasm

  • 创建一个HTML文件并编写JavaScript代码从服务器请求这个文件,并让这个模块完成实例化。

    • promise与箭头函数表达式

    • JavaScript对象简写

    • WebAssembly JavaScript API概览

    • 编写JavaScript代码来获取并实例化模块

      • 定义一个JavaScript对象,将其命名为importObject,它有一个名为env的子对象,其中包含一个memory_base属性,这是这个模块想要导入的。这个memory_base属性会简单持有一个0值,因为我们不会动态链接这个模块。

      • 创建好importObject后,就可以调用函数instantiateStreaming,传入Wasm文件的fetch方法的结果作为第一个参数,importObject作为第二个参数。

      • instantiateStreaming会返回一个promise,因此我们将设置一个处理函数作为成功回调,模块完成下载、编译并实例化后,它就会被调用。此时可以访问这个WebAssembly模块实例的导出元素并调用_Increment函数。

      • const importObject = {
             env: {
                 __memory_base: 0,
             }
        };
        WebAssembly.instantiateStreaming(fetch("side_module.wasm"),
        ➥ importObject).then(result => {
             const value = result.instance.exports._Increment(17);
             console.log(value.toString());
        });
        
    • 创建一个基本的HTML页面

      •  <script>
             const importObject = {
                 env: {
                     __memory_base: 0,
                 }
             };
             WebAssembly.instantiateStreaming(fetch("side_module.wasm"),
                 ➥ importObject).then(result => {
                     const value = result.instance.exports._Increment(17);
                     console.log(value.toString());
             });
         </script>
        

使用wasm模块中的函数

用C/C++创建带Emscripten plumbing的模块

  • 修改C++代码。

    • Emscripten的条件编译符号与头文件

      • Emscripten提供了条件编译符号__EMSCRIPTEN__,你可以用其检测正在编译这个解决方案的是否为Emscripten。

      • #include

        #include

        #ifdef EMSCRIPTEN ←---- 当代码被Emscripten编译时这个符号存在

        ​ #include <emscripten.h> ←---- Emscripten库的头文件

        #endif

    • extern "C"块

      • 在C++中,函数名可以被重载(overload),因此,编译时为了确保名称的唯一性,编译器会通过添加与函数参数相关的信息来改变它。编译代码时,编译器会修改函数名,这对于想要调用某个特定函数的外部代码来说是一个问题,因为那个函数名已经不复存在了。

      • 需要为函数包裹一个extern "C"块。将来要添加到这个文件中的所有函数都会放在这个块内。

      • #ifdef __cplusplus

        extern “C” { ←---- 因此编译器不会在这对大括号内重命名函数

        #endif

        ​ ←---- WebAssembly函数将放在这里

        #ifdef __cplusplus

        }

        #endif

  • 将代码编译为WebAssembly模块。

    • 在编写与模块交互的JavaScript代码时,将使用到Emscripten辅助函数ccall和UTF8ToString。

    • emcc validate.cpp -o validate.js

      ➥ -s EXTRA_EXPORTED_RUNTIME_METHODS=[‘ccall’,‘UTF8ToString’]

    • 辅助函数ccall:帮助调用模块函数,并在字符串希望只在调用期间存在时,辅助管理这些字符串的内 存。

    • 辅助函数UTF8ToString:这个函数接受一个指针,并从这个内存位置读取字符串。

  • 创建网页。

  • 创建与模块交互的JavaScript代码。

    • 将生成的文件复制到HTML文件所在目录,然后创建JavaScript代码与模块交互。

用C/C++创建不使用Emscripten的模块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-abg5HYV5-1670298706900)(/img/webassembly/0105.png)]

js和wasm的数据交互

// 没有更完,先鸽一下

更多内容在【倦倦喵.cn】~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值