Как лучше всего возвращать массив байтов из c ++ в веб-сборку и затем передавать этот байтовый массив в 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.
На inte rnet я видел 2 способа:
1) первый - передать в метод functionThatExtendsTheOriginalStringsAndReturnsAnotherString третий параметр, т.е. другое целое число, которое уже находится в Module.HEAPU8 и пусть c ++ initializ ie, тогда мне нужно будет прочитать, что из java script
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);
, первый целочисленный адрес - указатель на Вновь созданный байтовый массив, а второй - длина этого массива. Я не особо разбираюсь ни в одном из вышеперечисленных пунктов, так как кажется, что для чего-то, что должно быть легче сделать, требуется много работы.
Есть ли лучший способ сделать это?
Способ компиляции wasm из CMAKE
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']' " )
Дополнение 28 января 2020
В порядке чтобы прочитать последнюю строку обратно из Javascript Я снова использую эту
var output_array = new Uint8Array(Module.HEAPU8.buffer, extendedStringPtr, 90);
var newstring = new TextDecoder('utf8').decode(output_array);
console.log(newstring);
, здесь проблема в длине 90, так как мне нужно знать ее, прежде чем я начну читать строку обратно