WebAssembly数组传递(输⼊篇)接着输出篇,接下来就讲输⼊的操作
*注意:在使⽤emscripten::val和emscripten::bind时,编译时要带上--bind参数
传统法:
JS:
var ptr = Module._malloc(myTypedArray.length * myTypedArray.BYTES_PER_ELEMENT);
Module.HEAPF64.set(myTypedArray, ptr); //HEAPF64是WebAssembly中double*的存储位置
Module.setValue(ptr * 8, myTypedArray.length); //8代表sizeof(double)
附上类型对照表:
内存数组对应类型
HEAP8char*
HEAP16short int*
HEAP32int*
HEAPU8unsigned char*
HEAPU16unsigned short int*
HEAPU32unsigned int*
HEAPF32float*
HEAPF64double*
C++:
#include <emscripten/val.h>
#include <emscripten/bind.h>
using namespace std;
using namespace emscripten;
void setValue(int ptr, int len){
double *data;
data = (double *)ptr;
for(int i = 0; i < len; i ++){
cout << data[i] <<endl;
}
}
优点:速度中等
缺点:需要JS端操作,⽐较⿇烦
val class法:js 二维数组
JS:
Module.setValue(myTypedArray);
C++:
#include <emscripten/val.h>
#include <emscripten/bind.h>
using namespace std;
using namespace emscripten;
void setValue(val data){
for(int i = 0; i < len; i ++){
cout << data[i].as<double>() <<endl;
}
}
val通过as<type>⽅法可以将js数据转换为C++的原⽣类型
优点:js调⽤简单,整体直观
缺点:速度最慢
回归本质:
double *getDoublePtrFrom1XArray(val arr, int *len = NULL){
if(len == NULL) len = new int[1];
*len = arr["length"].as<int>();
double *ret = new double[*len];
val module = val::global("Module");
int ptr = (int)ret / sizeof(double);
module["HEAPF64"].call<val>("set", arr, val(ptr));
return ret;
}
优点:js调⽤简单,速度最快
缺点:暂时没发现
另:附上⼆维数组的解析
double **getDoublePtrFrom2XArray(val arr, int *y_len = NULL, int *x_len = NULL){ if(y_len == NULL) x_len = new int[1];
if(x_len == NULL) x_len = new int[1];
*y_len = arr["length"].as<int>();
val module = val::global("Module");
int ptr;
if(*y_len > 0){
*x_len = arr[0]["length"].as<int>();
double **ret = new double*[*y_len];
for(int i = 0; i < *y_len; i ++){
ret[i] = new double[*x_len];
ptr = (int)ret[i] / sizeof(double);
module["HEAPF64"].call<val>("set", arr[i], val(ptr));
}
return ret;
} else {
*x_len = 0;
return NULL;
}
}
因为⽬前还没有wasm的,所以⾃⼰建了个:866749590有问题可以相互帮助
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论