WebAssembly陣列傳遞(輸入篇)
阿新 • • 發佈:2018-12-11
接著輸出篇,接下來就講輸入的操作
*注意:在使用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)
附上型別對照表:
記憶體陣列 | 對應型別 |
---|---|
HEAP8 | char* |
HEAP16 | short int* |
HEAP32 | int* |
HEAPU8 | unsigned char* |
HEAPU16 | unsigned short int* |
HEAPU32 | unsigned int* |
HEAPF32 | float* |
HEAPF64 | double* |
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:
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
有問題可以相互幫助