如何在vue.js中调用Webassembly方法?

问题描述 投票:1回答:1

我正在尝试将这个简单的html页面add.html转换为vue.js:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <input type="button" value="Add" onclick="callAdd()" />

    <script>
      function callAdd() {
        const result = Module.ccall('Add',
            'number',
            ['number', 'number'],
            [1, 2]);

        console.log(`Result: ${result}`);
      }
    </script>
    <script src="js_plumbing.js"></script>
  </body>
</html>

它调用add.c中定义的Add函数:

#include <stdlib.h>
#include <emscripten.h>

// If this is an Emscripten (WebAssembly) build then...
#ifdef __EMSCRIPTEN__
  #include <emscripten.h>
#endif

#ifdef __cplusplus
extern "C" { // So that the C++ compiler does not rename our function names
#endif

EMSCRIPTEN_KEEPALIVE
int Add(int value1, int value2) 
{
  return (value1 + value2); 
}

#ifdef __cplusplus
}
#endif

并通过命令转换为js_plumbing和js_plumbling.wasm文件:

emcc add.c -o js_plumbing.js -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap'] -s 
ENVIRONMENT='web','worker'

在Google Chrome浏览器的控制台中,出现以下错误:

GET http://localhost:8080/dist/js_plumbing.wasm 404 (Not Found)  @  js_plumbing.js?2b2c:1653

在js_plumbing_js中:

// Prefer streaming instantiation if available.
  function instantiateAsync() {
    if (!wasmBinary &&
        typeof WebAssembly.instantiateStreaming === 'function' &&
        !isDataURI(wasmBinaryFile) &&
        typeof fetch === 'function') {
      fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) {  // <---------------!!!
        var result = WebAssembly.instantiateStreaming(response, info);
        return result.then(receiveInstantiatedSource, function(reason) {
            // We expect the most common failure cause to be a bad MIME type for the binary,
            // in which case falling back to ArrayBuffer instantiation should work.
            err('wasm streaming compile failed: ' + reason);
            err('falling back to ArrayBuffer instantiation');
            instantiateArrayBuffer(receiveInstantiatedSource);
          });
      });
    } else {
      return instantiateArrayBuffer(receiveInstantiatedSource);
    }
  }

在Google Chrome中:createWasm @ js_plumbing.js?2b2c:1680

js_plumbing.js的第1680行:

instantiateAsync();

在Google Chrome中:eval @ js_plumbing.js?2b2c:1930

js_plumbing.js的1930行:

<pre><font color="#4E9A06">var</font> asm = createWasm();</pre>

以及与wasm相关的许多其他错误:

enter image description here

enter image description here

所以...为了正确执行js_plumbing.js和js_plumbing.wasm文件中的Add函数,我应该如何修改Result.vue中的callAdd()方法?

  methods: {
    callAdd() {
      const result = Module.ccall('Add',
          'number',
          ['number', 'number'],
          [1, 2]);
      console.log('Result: ${result}');
    }
  }

更新:

1个更新)

我使用以下命令编译了add.c:

emcc add.c -o js_plumbing.mjs -s EXTRA_EXPORTED_RUNTIME_METHODS=
['ccall','cwrap'] -s ENVIRONMENT='web' . 

然后创建了一个js_plumbing.js文件:

. import wasm from './js_plumbing.mjs';

const instance = wasm({
  onRuntimeInitialized() {
    console.log(instance._addTwoNumbers(3,2));
  }
}) . 

正在执行npm run dev:

Failed to compile.

./src/components/js_plumbing.mjs 3:25
Module parse failed: Unexpected token (3:25)
You may need an appropriate loader to handle this file type, currently 
no loaders are configured to process this file. 
See https://webpack.js.org/concepts#loaders
| 
| var Module = (function() {
>   var _scriptDir = import.meta.url;
|   
|   return (

马可

javascript c vue.js webassembly
1个回答
1
投票

首先,应解决404错误。文件/dist/js_plumbing.wasm是否存在?过去,我需要手动复制.wasm文件,因为某些自动构建系统(如Parcel)目前不需要。

您可以使用MODULARIZE选项进行构建以导入到构建系统中。

addTwoNumbers.c

#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
int addTwoNumbers(int value1, int value2) 
{
  return (value1 + value2); 
}

build command

$ emcc -o dist/addTwoNumbers.js -s MODULARIZE=1 src/addTwoNumbers.c

JavaScript实现

import wasmModule from './addTwoNumbers.js';

const instance = wasmModule({
  onRuntimeInitialized() {
    console.log(instance._addTwoNumbers(3,2));
  }
})

使用onRuntimeInitialized方法来检测WASM模块何时准备就绪。您导出的函数前面将带有下划线。

require()可以代替import

const wasmModule = require('./addTwoNumbers.js');

...
© www.soinside.com 2019 - 2024. All rights reserved.