WebAssembly-实践二:在React使用C/C++函数

回顾

上一篇文章(WebAssembly-初探:在web环境运行C++)粗略的介绍了一下什么是WebAssembly,同时用一个demo来说明如何把C/C++代码编译为.wasm文件,那么在实际生产中,我们如何使用WebAssembly呢,这一偏文章将从React中来调用C代码的形式讲解一下如何使用。

准备wasm函数

基于上一篇文章的例子,我们重新修改一下hello.c,增加一个add函数来支持两个数字相加

#include <stdio.h>
#include <emscripten/emscripten.h>

int main(int argc, char ** argv) {
    printf("Hello World\n");
}

#ifdef __cplusplus
extern "C" {
#endif

int EMSCRIPTEN_KEEPALIVE add(int a, int b) {
  return a+b;
}

#ifdef __cplusplus
}
#endif
复制代码

然后用命令生成对应的js和wasm文件(注:这里不需要生成html文件,因此命令有些变化)

emcc hello.c -o ./hello.js -g1 -s WASM=1 -s MODULARIZE=1 -s EXPORT_ES6=1 -s 'EXPORT_NAME="hello"' -s "EXPORTED_RUNTIME_METHODS=['ccall','cwrap']" -s 'ENVIRONMENT="web"

稍微解释一下参数

  • MODULARIZE 模块化,可以设置模块名字,减少import冲突
  • EXPORT_ES6 以ES6语法格式导出
  • EXPORT_NAME 指定模块名字
  • ENVIRONMENT 指定运行环境,这种设置为web

这样就生成了 hello.js和hello.wasm

创建react项目

这里就用最基础的

create-react-app test-wasm-react

然后将hello.js放到scr目录下,hello.wasm放到public目录下,如下设置

image.png

改写app.js,对wasm进行引用并使用

image.png

改造hello.js

这个时候是无法运行起来的,会有很多报错,我们需要对hello.js进行修改

  1. 增加eslint-disable

    在hello.js最上面增加

    /* eslint-disable */

  2. 修改路径import.meta.url

    将hello.js中var _scriptDir = import.meta.url;修改为var _scriptDir = './hello.wasm';,指定public目录

image.png

  1. 修改self.location.href

    scriptDirectory = self.location.href;修改为scriptDirectory = window.self.location.href;这样脚本目录就指定好了

image.png

  1. 删除二进制加载代码

    搜索wasmBinaryFile,注释掉其下方的getBinarygetBinaryPromise函数 如图:

image.png

上面这些动作可以写个sh脚本来完成,给些参考

sed -i.old '1s;^;/* eslint-disable */;'./hello.js

sed -i.old "s|import.meta.url|'./hello.wasm'|" ./hello.js

sed -i.old "s|self.location.href|window.self.location.href|" ./hello.js
复制代码

运行项目

yarn start

image.png

可以看到run后面已经对2,3做了add,至此一个最基本的C函数在react中可以正常运行了

后续更新

  1. 采用Rust来实现
  2. wasm语法
  3. 复杂功能C实现

喜欢的可以点赞关注,有问题评论吧

猜你喜欢

转载自juejin.im/post/7041485336350261278