回顾
上一篇文章(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目录下,如下设置
改写app.js,对wasm进行引用并使用
改造hello.js
这个时候是无法运行起来的,会有很多报错,我们需要对hello.js进行修改
-
增加eslint-disable
在hello.js最上面增加
/* eslint-disable */
-
修改路径import.meta.url
将hello.js中
var _scriptDir = import.meta.url;
修改为var _scriptDir = './hello.wasm';
,指定public目录
-
修改self.location.href
将
scriptDirectory = self.location.href;
修改为scriptDirectory = window.self.location.href;
这样脚本目录就指定好了
-
删除二进制加载代码
搜索
wasmBinaryFile
,注释掉其下方的getBinary
和getBinaryPromise
函数 如图:
上面这些动作可以写个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
可以看到run后面已经对2,3做了add,至此一个最基本的C函数在react中可以正常运行了
后续更新
- 采用Rust来实现
- wasm语法
- 复杂功能C实现
喜欢的可以点赞关注,有问题评论吧