WebAssembly之数据交换(数组传值 js->c++)
因为工作需要,又倒腾起了WebAssembly,这次主要探索(解决)的问题是Array类型数据的传递
经过咨询以及与ChatGPT的沟通,目前有了如下三种方案:
1.通过类型化数组传递
1 //c++ 2 double EMSCRIPTEN_KEEPALIVE add(const double position[3]) 3 { 4 double ret = position[0] + position[1] + position[2]; 5 return ret; 6 }
1 //javascript 2 function toTypedArray_Double(arr) { 3 var buf = new ArrayBuffer(arr.length * 8); 4 var i8 = new Uint8Array(buf); 5 6 var i64 = new Float64Array(buf); 7 arr.forEach((i, index) => { 8 i64[index] = i; 9 }); 10 11 return i8; 12 } 13 14 var data = toTypedArray_Double([1.111111111111, 2.0, -13.0]); 15 var fn = Module.cwrap("add", "number", ["array"]); 16 console.log(fn(data));//-9.888888888889
1 //编译指令 2 emcc a.cpp -s EXPORTED_RUNTIME_METHODS=['cwrap','ccall'] -s EXPORTED_FUNCTIONS="['ccall', 'cwrap']" -o a.out.js
2.通过emsdk的bind.h转为vector
1 //c++ 2 #include <emscripten/emscripten.h> 3 #include <emscripten/bind.h> 4 #include <vector> 5 6 using namespace emscripten; 7 8 double EMSCRIPTEN_KEEPALIVE bar(const double position[3]) 9 { 10 double ret = position[0] + position[1] + position[2]; 11 return ret; 12 } 13 14 EMSCRIPTEN_BINDINGS(example) 15 { 16 emscripten::register_vector<double>("VectorDouble"); 17 18 // 增加function,使用const double *参数 19 emscripten::function("bar", &bar, emscripten::allow_raw_pointers()); 20 }
1 //javascript 2 var bar = Module.cwrap("bar", "number", ["array"]); 3 console.log(bar([1.111111111111, 2.0, -13.0]));//-9.888888888250108
1 //emcc编译指令(注意必须要加--bind) 2 emcc --bind a.cpp -s EXPORTED_RUNTIME_METHODS=['cwrap','ccall'] -s EXPORTED_FUNCTIONS="['ccall', 'cwrap']" -o a.out.js
3.通过自定义结构体以及value_array
1 //c++ 2 struct Array2d 3 { 4 double x; 5 double y; 6 }; 7 8 Array2d EMSCRIPTEN_KEEPALIVE foo(Array2d &arr) 9 { 10 Array2d ret = {arr.x, arr.y}; 11 return ret; 12 } 13 14 EMSCRIPTEN_BINDINGS(example) 15 { 16 value_array<Array2d>("Array2d") 17 .element(&Array2d::x) 18 .element(&Array2d::y); 19 function("foo", &foo); 20 }
1 //javascript 2 console.log(Module.foo([1.1, 2.2]));
1 //emcc编译指令(注意必须要加--bind) 2 emcc --bind a.cpp -s EXPORTED_RUNTIME_METHODS=['cwrap','ccall'] -s EXPORTED_FUNCTIONS="['ccall', 'cwrap']" -o a.out.js
待续...
(我不怕千万人阻挡,只怕自己投降!)