如何在Vue.js中加载emscripten生成的模块以使用其功能? [英] How load an emscripten generated module in Vue.js in order to use its functions?

查看:440
本文介绍了如何在Vue.js中加载emscripten生成的模块以使用其功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以在这里阅读:



我找到导入emscripten生成的Module并使用其功能的唯一方法,是使用一种 hack:在js_plumbing_js的Module定义中手动添加 export关键字,这是通过使用以下方法编译add.c生成的javascript文件:

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

Result.vue:

 < template> 
< div>
< p按钮@ click = callAdd>添加!< / p>
< p>结果:{{结果}}< / p>
< / div>
< / template>

< script>
导入*作为'./js_plumbing'的js_plumbing
导入'./js_plumbing'的模块
导出默认值{
data(){
return {
结果:null
}
},
方法:{
callAdd(){
const result = js_plumbing.Module.ccall('Add',
'数字',
['数字','数字'],
[1,2]);
this.result =结果;
}
}
}
< / script>

js_plumbing.js:

  //版权所有2010 The Emscripten作者。版权所有。 
// Emscripten有两个单独的许可证,即MIT许可证和
//伊利诺伊大学/ NCSA开源许可证。这两个许可证都可以在LICENSE文件中找到
//。

//模块对象:我们与外界的接口。我们导入
//并导出其值。有多种使用模块的方式:
// 1.未定义。我们在这里创建
// // 2.函数参数function(Module){..生成的代码..}
// // 3.将其附加到运行前,var Module = {}; ..生成的代码..
// // 4.外部脚本标记定义了var模块。
//我们需要检查模块是否已经存在(例如上述情况3)。
//替换将在构建的后期阶段用实际代码替换,
//这样,Closure Compiler不会处理它(例如,上面的情况4)。
//注意,如果要运行闭包,并且还要在生成的代码之后使用Module
//,则需要定义var Module = {};。
//在代码之前。然后,该对象将在代码中使用,并且您
//之后也可以继续使用Module。
export var Module = typeof Module!==未定义?模块:{};



但是,正如我所说,我不喜欢这种手动破解。
关于如何使模块可导出,从而可导入,而无需在js_plumbing.js文件中手动添加导出的任何建议?



1°更新) p>

遵循此处的回答指示:

解决方案

 从'./js_plumbing'导入模块; 

let实例= {
就绪:new Promise(resolve => {
Module({
onRuntimeInitialized(){
instance = Object.assign (this,{
ready:Promise.resolve()
});
resolve();
}
});
})
};

导出默认值{
data(){
return {
结果:null
};
},
方法:{
callAdd(a,b){
instance.ready
.then(_ => this.result = instance._Add( a,b));
}
}
};


As you can read here: https://forum.vuejs.org/t/wasm-how-to-correctly-call-a-webassembly-method-in-vue-js/83422/24 I'm trying to figure out how to import a module generated by emscripten in Vue.js in order to call its methods.

Following the indications found here: How load an emscripten generated module with es6 import? I compiled add.c with this command:

emcc add.c -o js_plumbing.js -s EXPORTED_FUNCTIONS="['_Add']" -s  
EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap'] -s EXPORT_ES6=1 -s 
MODULARIZE=1

and modified Result.vue accordingly in this way:

<template>
  <div>
    <p button @click="callAdd">Add!</p>
    <p>Result: {{ result }}</p>
  </div>
</template>

<script>
    import Module  from './js_plumbing'
    const mymod = Module();
    export default {
      data () {
        return {
          result: null
        }
      },
      methods: {
        callAdd() {
          const result = mymod.cwrap('Add',
            'number',
            ['number', 'number'],
            [1, 2]);
          this.result = result;
        }
      }
    }
</script>

But I got this error:

Failed to compile.

./src/components/js_plumbing.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: Unexpected token, expected ( (3:25)

  1 | 
  2 | var Module = (function() {
> 3 |   var _scriptDir = import.meta.url;
    |                          ^
  4 |   
  5 |   return (
  6 | function(Module) {

The only way I found to import emscripten generated Module and use its functions, is to use a sort of an "hack": manually adding 'export' keyword in the Module definition in js_plumbing_js, the javascript file generated by compiling add.c with:

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

Result.vue :

<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>

js_plumbing.js :

// 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 : {};

But, as I said, I do not like this manual hack. Any suggestions on how to make the Module exportable, thus importable, without manually adding ‘export’ in js_plumbing.js file?

1° Update)

Following the indications of the answer here: How to call a webassembly method in vue.js?

I compiled the add.c file in this way:

emcc add.c -o js_plumbing.js -s MODULARIZE=1

and then modified Result.vue as follows:

<template>
  <div>
    <p button @click="callAdd">Add!</p>
    <p>Result: {{ result }}</p>
  </div>
</template>

<script>
    import Module from './js_plumbing'
    export default {
      data () {
        return {
          result: null
        }
      },
      methods: {
        callAdd() {
          const instance = Module({
            onRuntimeInitialized() {
              console.log(instance._Add(1,2));
              this.result = instance._Add(1,2);
            }
          })
        }
      }
    }
</script>

There must be something I'm doing wrong, since I do get the console.log when clicking to the Add! button,but the output is not transferred to the the html part of Result.vue:

解决方案

import Module from './js_plumbing';

let instance = {
  ready: new Promise(resolve => {
    Module({
      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));
    }
  }
};

这篇关于如何在Vue.js中加载emscripten生成的模块以使用其功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆