通过WasmFiddle平台构建WASM模块
1.WasmFiddle在线平台网址
https://wasdk.github.io/WasmFiddle/
2.编写C++源代码
#define N 10
//定义将从javascript环境导入的函数
extern void print(int* offset,int length);
//声明用于排序的全局数组,在模块初始化时就已在内存中生成
int array[N];
//用于在js环境中获取待排数组首地址的方法
int* getArrayOffset(){
return array;
}
//交换函数
void swap(int *a,int *b){
int temp;
temp=*a;
*a=*b;
*b=temp;
return;
}
//核心快排
void quicksort_core(int array[],int maxlen,int begin,int end){
int i,j;
if(begin<end){
i=begin+1;
j=end;
while(i<j){
if(array[i]>array[begin]){
swap(&array[i],&array[j]);
j--;
}else{
i++;
}
}
if(array[i]>=array[begin]){
i--;
}
swap(&array[begin],&array[i]);
quicksort_core(array,maxlen,begin,i);
quicksort_core(array,maxlen,j,end);
}
}
//用于在js环境中调用的主排序的方法
void sort(){
quicksort_core(array,N,0,N-1);
//调用从js环境导入的“打印”方法
print(array,N);
}
extern是计算机语言中的一个关键字,可置于变量或者函数前,以表示变量或者函数的定义在别的文件中。
3.点击Build启动编译
4.下载Wasm模块
5.编写html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的第一个WASM应用</title>
</head>
<body>
<p><span>排序前:</span><span class="sequence-before"></span></p>
<p><span>排序后:</span><span class="sequence-after"></span></p>
<script>
//该方法用于从js环境向指定的共享堆内存段填充数据
function importArrayToBuffer(memory,array,offset) {
const importBuffer = new Uint32Array(memory.buffer,offset,array.length);
for(let i=0;i<array.length;i++){
importBuffer[i] = array[i];
}
}
//从远程加载一个WASM的模块,并将该模块中的内容转换成二进制数据
let startTime = performance.now();
fetch("/cctest/original.wasm").then(response => response.arrayBuffer()).then((bytes) =>{
let memory;
//通过浏览器提供的标准WebAssembly接口来编译和初始化一个Wasm模块
WebAssembly.compile(bytes).then(module => WebAssembly.instantiate(module,{
env:{
print (offset,len){
let strBuffer = new Uint32Array(memory.buffer,offset,len);
document.querySelector('.sequence-after').innerText=JSON.stringify(Object.values(strBuffer));
}
}
})).then(instance =>{
//输出下载,编译及实例化模块花费的时间
console.log(performance.now()-startTime);
//取出从Wasm模块中导出的函数
let exports = instance.exports;
//wasm实例所有信息
console.log("实例的所有信息");
console.log(exports);
//获取该Wasm模块实例使用的堆内存对象
memory=exports.memory;
let arr =[];
for(let i=0;i<10;i++){
arr.push(Math.round(Math.random()*10));
}
document.querySelector('.sequence-before').innerText=JSON.stringify(arr);
//将整型数组内的元素依次填充到指定的内存段,即填充到Wasm模块初始化时生成的数组中
importArrayToBuffer(memory,arr,exports.getArrayOffset());
//调用Wasm模块暴露的排序函数
exports.sort();
});
});
</script>
</body>
</html>
6.在IDEA中构建一个Web应用然后启动
推荐js方法二
利用WebAssembly.instantiateStreaming()方法,可直接从系统底层的数据流源来编译并实例化一个Wasm模块
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的第一个WASM应用</title>
</head>
<body>
<p><span>排序前:</span><span class="sequence-before"></span></p>
<p><span>排序后:</span><span class="sequence-after"></span></p>
<script>
function importArrayToBuffer(memory,array,offset) {
const importBuffer = new Uint32Array(memory.buffer,offset,array.length);
for(let i=0;i<array.length;i++){
importBuffer[i] = array[i];
}
}
let startTime = performance.now();
WebAssembly.instantiateStreaming(fetch("/cctest/original.wasm"),{
env:{
print (offset,len){
let strBuffer = new Uint32Array(memory.buffer,offset,len);
console.log(strBuffer);
document.querySelector('.sequence-after').innerText=JSON.stringify(Object.values(strBuffer));
}
}
}).then(resultObject =>{
console.log(performance.now()-startTime);
//WebAssembly.Module
console.log(resultObject.module);
//WebAssembly.Instance
console.log(resultObject.instance);
//总和
console.log(resultObject);
let exports = resultObject.instance.exports;
memory=exports.memory;
let arr =[];
for(let i=0;i<10;i++){
arr.push(Math.round(Math.random()*10));
}
document.querySelector('.sequence-before').innerText=JSON.stringify(arr);
importArrayToBuffer(memory,arr,exports.getArrayOffset());
exports.sort();
});
</script>
</body>
</html>
注意:出现错误
Uncaught (in promise) TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
因为 从远程服务器加载的Wasm模块文件只有在其HTTP相应结果中被标识为application/wasm
类型,才可以被WebAssembly.instantiateStreaming方法正确的编译和处理
解决办法:我这里的情况是这样用的springboot的tomcat,所以修改tomcat的mime类型,多添加一个wasm的类型
https://www.jianshu.com/p/275977cda752
关系图
摘抄自网络,便于检索查找。