花褪残红青杏小。燕子飞时,绿水人家绕。

小程序WXWebAssembly能力调用c++编译的wasm文件

菜鸟编程 十五楼的鸟儿 12851浏览 0评论

先吐槽:微信官方基本等于没有文档:https://developers.weixin.qq.com/miniprogram/dev/framework/performance/wasm.html

没有范例,搜索到的内容也很有限,还有些文档过期了。还有些不知道是在胡说八道还是我没看懂,反正测试无效。

整理本文,以备查询。

 

一、安装环境。

这里可以参照:https://developer.mozilla.org/zh-CN/docs/WebAssembly/C_to_wasm   但不要全信。上下文有助于理解WASM是个啥。

安装Git https://git-scm.com/download/win
安装Cmake https://cmake.org/download/
安装Python https://www.python.org/downloads/

PS:我没看到哪里用到了python,后续使用的时候都是直接用emcc这个指令。至于git,可有可无,国内环境建议用githubdesktop,这样下载文件更完整。git clone命令行有时候下载失败或者下载不完整。

 

找个没有中文的路径,我这里是E:\盘根目录,创建文件夹emsdk。然后把emsdk的内容下载进去。

git clone https://github.com/emscripten-core/emsdk
安装emsdk
cd emsdk

./emsdk install latest
./emsdk activate latest

此时你需要设置环境变量:

E:\emsdk
E:\emsdk\node\16.20.0_64bit\bin
E:\emsdk\upstream\emscripten

没有验证过是否都需要设置,至少需要第一个。不然emcc找不到路径。

 

二、编写c代码。

这里可以参照https://developers.weixin.qq.com/community/develop/article/doc/000ea84136c8103d40bfb02865b813 但不要全信。上下文有助于理解微信的WASM是个啥。

最小化demo可以如下:

char* toChar (char* str) {
return str;
}

int add (int x, int y) {
return x + y;
}

int square (int x) {
return x * x;
}
int test (int x, int y) {
return log(x);
}

实测加入头文件没有任何问题,比如。

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

三、编译

cmd进入当前文件夹,输入以下命令进行编译,会得到一个demo.wasm

emcc --no-entry -Os demo.c -o refdb.wasm -s EXPORTED_FUNCTIONS="['_test']"

如果你不想使用EXPORTED_FUNCTIONS导出函数,也可以在函数名的上一行加上EMSCRIPTEN_KEEPALIVE标记。

比如:

EMSCRIPTEN_KEEPALIVE
double GetRefStat(enum RefrnameList refr, double prtr, int refrstate, int calctype)
{
  return 0;
}

如果使用后一种方法,注意c文件的头部加上

#include <emscripten.h>

编译指令可以简化为

emcc --no-entry -Os demo.c -o refdb.wasm 

注意:

1、仅限于这条指令,具体原因可能是某个编译指令不一样会导致调用失败。所以不想折腾就用这个。

2、请保持文件名的扩展名为.c,如果使用.cpp会有不可预知的问题。

四、小程序调用

 

在页面JS的Page内,加上这个函数:

    loadWasm() {
        var importObject = {};
        WXWebAssembly.instantiate("demo.wasm", importObject).then(
            (result) => {
                console.log("初始化成功");
                //注意:这里这个inst可以存到当前页面的data里,留着后面用。
                let inst = result.instance.exports;
                let sum = inst.test(11, 22);
                console.log(sum);
            },

            (err) => {
                console.log("初始化失败", err);
            }
        );
    },
 
在onShow里加上:
        this.loadWasm();
 
如果正常,小程序开发工具控制台会显示计算加法11+22的计算结果:33。

小程序WXWebAssembly能力调用c++编译的wasm文件  菜鸟编程  第1张

 

五、总结

1、不需要什么胶水js以及修改胶水js,不需要奇怪的引用。按照这个方法可以最简单的进行调用。复杂的。。。不知道,以后再说。

2、目前唯一缺点,没有找到合适的技术链工具,只能在VSCode中调试编译,再到emcc命令下编译生成wasm。由于二者有些环境变量似乎不一致,导致互相报错的内容不完全相同。

目前解决方案是尽量再VSCode中代码简化,调试通过后再梳理成emcc能接受的内容(比如头文件),或者分段进行调试编译验证。

转载请注明:鸟儿博客 » 小程序WXWebAssembly能力调用c++编译的wasm文件

游客
发表我的评论 换个身份
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址