emscriptem - как читать C-массив из JavaScript (Chrome / Firefox)?

1

Здесь мой код C:

// helloworld.c
#include <stdio.h>
#include <emscripten.h>

int* EMSCRIPTEN_KEEPALIVE getIntArray(){
    static int numbers[] = {1, 2, 4, 8, 16};
    return numbers;
}

Вот некоторые из моих JS:

// helloworld.html
let result = Module.ccall('getIntArray', // name of C function
  'Uint8Array', // return type
  [null], // argument types
  [null]); // arguments

let array = new Uint8Array(result,5);

console.log(result); // prints 1024
console.log(array); // prints Uint8Array(1024) [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … ]

Все это компилируется и работает отлично. Вышеприведенный код отлично работает для примитивных значений, но не работает с указателем массива, а массив ввода JS, который я возвращаю, - это все нули. Я видел некоторые другие решения в документации, но они, похоже, тоже не работают для меня.

  • 0
    Ваша функция возвращает указатель, который является целым числом, а не массивом. На самом деле в C. нет типов массивов. Вам понадобится доступ к куче, чтобы вывести нужный раздел из памяти . Чтобы упростить задачу, существует модуль npm, который можно использовать для работы с массивами.
  • 0
    Изменил мою функцию C на этот, тот же результат: int8_t* EMSCRIPTEN_KEEPALIVE getIntArray(){ static int8_t numbers[] = {1, 2, 4, 8, 16}; return &numbers[0]; }
Показать ещё 2 комментария
Теги:
webassembly
emscripten

1 ответ

3
Лучший ответ

Функция getIntArray будет возвращать целое число, которое является расположением массива в линейной памяти модулей WebAssembly. Чтобы использовать это, вам понадобится ссылка на линейную память модуля.

Один из вариантов - создать линейную память со стороны JavaScript:

const imports = {
    env: {
      memoryBase: 0,
      tableBase: 0,
      memory: new WebAssembly.Memory({
        initial: 512
      }),
      table: new WebAssembly.Table({
        initial: 0,
        element: 'anyfunc'
      })
    }
  };

  const instance = new WebAssembly.Instance(module, imports);

Затем вы можете использовать возвращаемый результат, который будет целочисленным, как смещение в линейную память:

 const result = Module.ccall('getIntArray', // name of C function
  'Uint8Array', // return type
  [null], // argument types
  [null]); // arguments

  const data = new Uint8Array(imports.env.memory.buffer, result, 5);
  • 0
    Последняя строка const data = new Uint8Array(imports.env.memory.buffer, result, 5); сделал это - спасибо большое!
  • 0
    Это отличное объяснение! Знаете ли вы, где / если это задокументировано?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню