将c ++的字节数组返回到webassembly,然后将该字节数组传递给Javascript Uint8Array的最佳实践是什么?>
目前,我有一个将字符串作为参数的c ++方法
var theString = 'The quick brown fox jumps over the lazy dog'; const encoder = new TextEncoder(); const input_array = encoder.encode(theString); var len = input_array.length; var bytes_per_element = input_array.BYTES_PER_ELEMENT; var input_ptr = Module._malloc(len * bytes_per_element ); Module.HEAPU8.set(input_array, input_ptr / bytes_per_element); // write WASM memory calling the set method for the Uint8Array var extendedStringPtr = Module._functionThatExtendsTheOriginalStringsAndReturnsAnotherString(input_ptr, len ); var extendedStringLength = 90 var output_array = new Uint8Array(Module.HEAPU8.buffer, extendedStringPtr, extendedStringLength); var newstring = new TextDecoder('utf8').decode(output_array); console.log(newstring); Module._free(input_ptr);
和c ++部分
char* EMSCRIPTEN_KEEPALIVE functionThatExtendsTheOriginalStringsAndReturnsAnotherString( char* str, int length ) { string s1(str, length); std::cout << "original string received from JavaScript is :" << s1 << std::endl; string s2 = ", then Godzilla jumps out and party is over! :)"; string s3 = s1 + s2; std::cout << "Final string " << s3 << std::endl; std::cout << "Final string length " << s3.length() << std::endl; // create a character buffer to return char * char_array = new char [s3.length()+1]; strcpy (char_array, s3.c_str()); // create a char pointer and return it char* arrayPtr = &char_array[0]; return arrayPtr; }
现在问题出在“ extendedStringLength”,即我在这个特定的时间点还没有它。我如何以最方便的方式将其从C ++传递到javascript。
在互联网上,我见过两种方式:
1)首先是将第三个参数传递给函数ThatExtendsTheOriginalStringsAndReturnsAnotherString方法,即另一个已经存在于Module.HEAPU8中的整数,然后让c ++对其进行初始化那么我将不得不从Java脚本中读取它
2)创建一个固定长度的结构,例如
struct MyControllStruct { uint32_t* arrayBufferPtr; uint32_t arrayBufferLength; };
https://dev.to/azure/passing-structured-data-from-c-to-javascript-in-web-assembly-1i0p并且由于我知道该结构正好是8个字节长,即4 + 4,因此每次都必须在JavaScript中像这样读取它
var MyControllStruct = new Int32Array(Module.HEAP32.buffer, output_ptr, 8);
第一个整数地址是指向新创建的字节数组的指针,第二个整数地址是该数组的长度。我对上述2种方法中的任何一种都没有特别的发现,因为对于应该更容易完成的事情而言,似乎有很多工作要做。
有更好的方法吗?
从CMAKE编译wasm的方式
set_target_properties(wasmExec PROPERTIES LINK_FLAGS "-std=c++17 -s WASM=1 -s TOTAL_MEMORY=512MB -s NO_EXIT_RUNTIME=1 -s VERBOSE=1 --pre-js /src/wasm/preModule.js -s DEMANGLE_SUPPORT=1 -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s EXTRA_EXPORTED_RUNTIME_METHODS='['cwrap', 'getValue', 'setValue']' " )
2020年1月28日增加
为了从JavaScript读取最终的字符串,我使用了此
var output_array = new Uint8Array(Module.HEAPU8.buffer, extendedStringPtr, 90); var newstring = new TextDecoder('utf8').decode(output_array); console.log(newstring);
同样在这里问题是长度90,因为我需要在开始读回字符串之前就知道长度
最佳做法是将字节数组从c ++返回到Webassembly,然后将该字节数组传递给Javascript Uint8Array。目前,我有一个c ++方法,该方法将字符串作为参数...
问题是长度90,因为我需要在开始读回字符串之前就知道长度