Как получить файл JSON в веб-сборке - PullRequest
0 голосов
/ 15 января 2019

В настоящее время я экспериментирую с Webassembly, и здесь я пытаюсь сделать одну вещь: Webassembly для извлечения данных из файла JSON, компилирования в модуль .wasm и использования этого модуля в Javascript для чтения результат выборки.

Я пытался следовать коду на https://kripken.github.io/emscripten-site/docs/api_reference/fetch.html, но полученный код .wasm сбивает меня с толку, потому что я не могу найти, как правильно загрузить этот модуль .wasm в Javascript.

Если я поступаю неправильно, мне действительно нужна помощь.

началось с этого файла fetch.c, который должен извлекать данные JSON из файла.

#include <stdio.h>
#include <string.h>
#include <emscripten/fetch.h>

/*////////////////////////
// This file contains the code for fetching
// -> Compiled to .wasm file with emscripten <-
*////////////////////////
void downloadSucceeded(emscripten_fetch_t *fetch) {
printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
// The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
emscripten_fetch_close(fetch); // Free data associated with the fetch.
}

void downloadFailed(emscripten_fetch_t *fetch) {
printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
emscripten_fetch_close(fetch); // Also free data on failure.
}

int main() {
emscripten_fetch_attr_t attr;
emscripten_fetch_attr_init(&attr);
strcpy(attr.requestMethod, "GET");
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_PERSIST_FILE;
attr.onsuccess = downloadSucceeded;
attr.onerror = downloadFailed;
emscripten_fetch(&attr, "./json/bol_list1.json");
}

Я скомпилировал это с: emcc wasm/fetch.c -Os -s WASM=1 -s FETCH=1 -s SIDE_MODULE=1 -s BINARYEN_ASYNC_COMPILATION=0 -o wasm/fetch.wasm fetch.wasm: https://pastebin.com/cHYpgazy

Итак, теперь с этим модулем я должен прочитать его в Javascript и получить результат, но я застрял здесь, потому что в отличие от других примеров этот модуль .wasm не имеет очевидного экспорта / Не удалось импортировать объект и мои предыдущие способы его загрузки.

wasmbyfile.js: Способ 1:

let obj;
loadWebAssembly('./wasm/fetch.wasm') //Testing function
.then(instance => {
    obj = instance.exports._main;
    console.log(obj);
});
function loadWebAssembly(fileName) {
    return fetch(fileName)
        .then(response => response.arrayBuffer())
        .then(bits => WebAssembly.compile(bits))
        .then(module => { return new WebAssembly.Instance(module) });
    };

результат ошибки: wasmbyfile.js: 64 Uncaught (в обещании) TypeError: WebAssembly Instantiation: аргумент Imports должен присутствовать и должен быть объектом в fetch.then.then.then.module (wasmbyfile.js: 64)

Метод 2:

(async () => {
    const fetchPromise = fetch('./wasm/fetch.wasm');
    const { instance } = await WebAssembly.instantiateStreaming(fetchPromise);
    const result = instance.exports._main;
    console.log(result);
})();

результат ошибки: Uncaught (в обещании) TypeError: WebAssembly Instantiation: аргумент Imports должен присутствовать и должен быть объектом

Так что я застрял на этом этапе и не совсем уверен, как правильно загрузить модуль в JS. Мне нужна помощь для этого, или я делаю это неправильно с самого начала, и есть ли лучший способ сделать это для меня?

1 Ответ

0 голосов
/ 16 января 2019

Вы получаете ошибку, потому что ваш WASM имеет операторы импорта, а ваш вызов instantiateStreaming не отправляет importObject.

Но основной способ использования WASM из Javascript намного проще, чем: просто определите функцию в WASM, которую вы можете вызвать из JS, а затем, например, выполните «выборку» из JS («add.wasm») :

(module
  (type $t0 (func (param i32 i32) (result i32)))
  (func $add (type $t0) (param $p0 i32) (param $p1 i32) (result i32)
    get_local $p0
    get_local $p1
    i32.add)
(export "add" (func $add)))

А затем позвоните из Javascript:

const wasmInstanceFromFile = await WebAssembly.instantiateStreaming(await fetch('add.wasm'));
let sum = wasmInstanceFromFile.instance.exports.add(1,2);
...