Javascript 如何在vue.js中调用webassembly方法?
我正在尝试将这个简单的html页面add.html转换为vue.js:Javascript 如何在vue.js中调用webassembly方法?,javascript,c,vue.js,emscripten,webassembly,Javascript,C,Vue.js,Emscripten,Webassembly,我正在尝试将这个简单的html页面add.html转换为vue.js: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> </head> <body> <input type="button" value="Add" onclick="callAdd()" /> <script> functio
<!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>
<pre><font color="#4E9A06">var</font> asm = createWasm();</pre>
在google chrome的控制台中,我发现以下错误:
GET http://localhost:8080/dist/js_plumbing.wasm 404 (Not Found) @ js_plumbing.js?2b2c:1653
在js_管道_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:eval@js_pipeoping.js?2b2c:1930中
js_plupping.js的第1930行:
更新:
1(更新)
我使用以下命令编译了add.c:
. import wasm from './js_plumbing.mjs';
const instance = wasm({
onRuntimeInitialized() {
console.log(instance._addTwoNumbers(3,2));
}
}) .
然后创建了一个js_plupping.js文件:
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 (
正在执行npm运行开发:
<template>
<div>
<p button @click="callAdd">Add!</p>
<p>Result: {{ result }}</p>
</div>
</template>
<script>
import * as js_plumbing from './js_plumbing'
import Module from './js_plumbing'
export default {
data () {
return {
result: null
}
},
methods: {
callAdd () {
const result = js_plumbing.Module.ccall('Add',
'number',
['number', 'number'],
[1, 2]);
this.result = result;
}
}
}
</script>
更新(2)
我解决了404错误,将wasm文件放入index.html文件的同一文件夹中的a/div子文件夹中
现在我面临这个问题:“无法读取未定义的属性'ccall'”
但是我编译了add.c文件,用这个命令创建了js_pipeoping.js和js_pipeoping.wasm文件,它导出了方法“ccall”和“cwrap”:
emcc add.c-o js_pipeoping.js-s EXTRA_EXPORTED_RUNTIME_方法=['ccall','cwrap']-s ENVIRONMENT='web','worker'
3°更新)
我通过一种我一点也不喜欢的黑客手段“解决”了这个问题
这是Result.vue文件:
// Copyright 2010 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT
license and the
// University of Illinois/NCSA Open Source License. Both these
licenses can be
// found in the LICENSE file.
// The Module object: Our interface to the outside world. We import
// and export values on it. There are various ways Module can be used:
// 1. Not defined. We create it here
// 2. A function parameter, function(Module) { ..generated code.. }
// 3. pre-run appended it, var Module = {}; ..generated code..
// 4. External script tag defines var Module.
// We need to check if Module already exists (e.g. case 3 above).
// Substitution will be replaced with actual code on later stage of
the build,
// this way Closure Compiler will not mangle it (e.g. case 4. above).
// Note that if you want to run closure, and also to use Module
// after the generated code, you will need to define var Module =
{};
// before the code. Then that object will be used in the code, and you
// can continue to use Module afterwards as well.
export var Module = typeof Module !== 'undefined' ? Module : {};
但是,正如我所说,我不喜欢这种黑客行为。
关于如何使模块可导出,从而可导入,而无需在js_plupping.js文件中手动添加“export”的任何建议
Marco首先,应该解决404错误。是否存在文件
/dist/js_pipeoping.wasm
?过去我需要手动复制.wasm文件,因为某些自动生成系统(如Parcel)目前不需要
您可以使用模块化
选项进行构建,以导入到构建系统中
添加两个数字。c
$ emcc -o dist/addTwoNumbers.js -s MODULARIZE=1 src/addTwoNumbers.c
Vue实施
const wasmModule = require('./addTwoNumbers.js');
...
使用onRuntimeInitialized
方法检测WASM模块何时准备就绪。导出的函数前面将有一个下划线
require()
可能用于代替import
:
您在Vue中使用哪种JS模块语法
require()
或import X from Y
?@anthumcris in/components/Result.vue:import*作为来自“/js_pipellowing”的js_pipellowing,这个线程看起来像是重复的。我更新了我的问题,结果是我尝试跟随你的hintsI更新了我的问题(更新2):解决了404错误消息,但现在我面临这个问题:“无法读取未定义的属性'ccall'”您如何在Result.vue中调用wasm Add函数?
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 (
<template>
<div>
<p button @click="callAdd">Add!</p>
<p>Result: {{ result }}</p>
</div>
</template>
<script>
import * as js_plumbing from './js_plumbing'
import Module from './js_plumbing'
export default {
data () {
return {
result: null
}
},
methods: {
callAdd () {
const result = js_plumbing.Module.ccall('Add',
'number',
['number', 'number'],
[1, 2]);
this.result = result;
}
}
}
</script>
// Copyright 2010 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT
license and the
// University of Illinois/NCSA Open Source License. Both these
licenses can be
// found in the LICENSE file.
// The Module object: Our interface to the outside world. We import
// and export values on it. There are various ways Module can be used:
// 1. Not defined. We create it here
// 2. A function parameter, function(Module) { ..generated code.. }
// 3. pre-run appended it, var Module = {}; ..generated code..
// 4. External script tag defines var Module.
// We need to check if Module already exists (e.g. case 3 above).
// Substitution will be replaced with actual code on later stage of
the build,
// this way Closure Compiler will not mangle it (e.g. case 4. above).
// Note that if you want to run closure, and also to use Module
// after the generated code, you will need to define var Module =
{};
// before the code. Then that object will be used in the code, and you
// can continue to use Module afterwards as well.
export var Module = typeof Module !== 'undefined' ? Module : {};
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int addTwoNumbers(int value1, int value2)
{
return (value1 + value2);
}
$ emcc -o dist/addTwoNumbers.js -s MODULARIZE=1 src/addTwoNumbers.c
import myMathModule from './js_plumbing';
let instance = {
ready: new Promise(resolve => {
myMathModule({
onRuntimeInitialized() {
instance = Object.assign(this, {
ready: Promise.resolve()
});
resolve();
}
});
})
};
export default {
data () {
return {
result: null
};
},
methods: {
callAdd(a, b) {
instance.ready
.then(_ => this.result = instance._add(a, b));
}
}
};
const wasmModule = require('./addTwoNumbers.js');
...