Ответ 1
Ожидаемый формат Module.cwrap позволяет передать массив в функцию, но будет утверждать результат и потерпеть неудачу, если вы попытаетесь вернуть массив
displayArrayA=Module.cwrap('displayArray','array',['array'])
displayArrayA([1,2,3])
// Assertion failed: ccallFunc, fromC assert(type != 'array')
Второе ограничение состоит в том, что входящие массивы, как ожидается, будут байт-массивами, то есть вам нужно будет преобразовать любые входящие двойные массивы в 8-битные числа без знака
displayArrayA=Module.cwrap('displayArray','number',['array'])
displayArrayA(new Uint8Array(new Float64Array([1,2,3]).buffer))
Вызов метода таким образом вызовет вашу функцию, временно скопировав ваши массивы в стек Emscripten, который будет reset после выполнения выведенной функции, что сделает возвращаемое смещение Array потенциально непригодным для использования, поскольку оно освобождает стеки.
Гораздо более предпочтительно, если вы хотите получить результаты своей функции, выделить и сохранить массив внутри системы Emscriptens Heap.
Код Emscripten доступен только для доступа к памяти, которая была выделена в пространстве Emscripten Heap. Массивы, которые вы пытаетесь передать в функцию, выделяются за пределами кучи, с которой выполняется код Emscripten, и не соответствуют ожидаемому в исходных аргументах типа необработанного указателя.
Существует несколько способов получить доступ к массиву для передачи данных в ваши функции. Все это требует, чтобы Emscripen знала расположение вашей памяти внутри emscripten Module.HEAP *, поэтому в какой-то момент начальный шаг вызывается функцией Emscripten "_malloc".
var offset = Module._malloc(24)
Это позволит вам выделить необходимые 24 байта в куче Emscripten, необходимой для вашего трехмерного 8-байтового массива с тремя байтами, и возвращает смещение Number в куче Emscripten, обозначающее смещение Typharray U8, зарезервированное для вашего массива. Это смещение является вашим указателем и будет автоматически работать в вашей функции displayArray cwrap, когда он настроен на использование смещений исходного указателя.
displayArray=Module.cwrap('displayArray','number',['number'])
В этот момент, если вы хотите получить доступ к содержимому массива или изменить его до тех пор, пока malloc действителен, у вас есть как минимум следующие параметры:
-
Задайте память с помощью временно упакованного массива Float64 без простого способа восстановить значение, за исключением следующих двух методов доступа
Module.HEAPF64.set(new Float64Array([1,2,3]), offset/8); displayArray(offset);
-
Module.setValue будет использовать подсказку 'double' для автоматического изменения смещения HEAPF64, деленного на 8.
Module.setValue(offset, 1, 'double') Module.setValue(offset+8, 2, 'double') Module.setValue(offset+16, 3, 'double') displayArray(offset) var result = []; result[0] = Module.getValue(offset,'double'); //98 result[1] = Module.getValue(offset+8,'double') //99 result[2] = Module.getValue(offset+16,'double') //100
-
Если вы хотите более подробно использовать указатель на стороне Javascript, вы можете вручную вывести Subarray TypedArray из записи HEAPF64. Это позволяет вам легко считывать значения, как только вы закончите выполнение своей функции. Этот TypedArray поддерживается той же кучей, что и остальная часть Emscripten, поэтому все изменения, выполненные на стороне Javascript, будут отражены на стороне Emscripten и наоборот:
var doublePtr = Module.HEAPF64.subarray(offset/8, offset/8 + 3); doublePtr[0] = 1; doublePtr[1] = 2; doublePtr[2] = 3; // Although we have access directly to the HEAPF64 of the pointer, // we still refer to it by the pointer byte offset when calling the function displayArray(offset); //doublePtr[] now contains the 98,99,100 values