项目背景

在项目中需要 大地坐标和经纬度之间互相转换, 基于已有的 cpp 代码,想通过 js 直接调用cpp 的函数。

  1. 前期准备

首先需要执行命令将 .cpp 文件编译出 .wasm文件 及 .js 文件

emcc main.cpp -o index.html -s EXPORTED_FUNCTIONS="['_setSeed','_mtrandom']" -s WASM=1

在上面执行的代码中, EXPORTED_FUNCTIONS 这个变量是用来指定你想要在 main.cpp 中暴露提供给 js调用的函数名称, 比如你想要在 .cpp 文件中 暴露调用的方法叫 compareMax,那么需要你在 .cpp 文件中定义了这个方法。
否则你在vue文件中引入之后调用会报错。

  1. 编译之后 有三个文件, 分别是 .wasm(必须), .html(可选), .js(必须)

在编译好的js文件中,我们可以看到类似于下面这种结构

var asm = createWasm();
/** @type {function(...*):?} */
var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors");

/** @type {function(...*):?} */
var _exchangeCoordinate = Module["_exchangeCoordinate"] = createExportWrapper("exchangeCoordinate");

/** @type {function(...*):?} */
var _getXCoordinate = Module["_getXCoordinate"] = createExportWrapper("getXCoordinate");

/** @type {function(...*):?} */
var _getYCoordinate = Module["_getYCoordinate"] = createExportWrapper("getYCoordinate");

/** @type {function(...*):?} */
var _getLoCoordinate = Module["_getLoCoordinate"] = createExportWrapper("getLoCoordinate");

/** @type {function(...*):?} */
var _getLaCoordinate = Module["_getLaCoordinate"] = createExportWrapper("getLaCoordinate");

/** @type {function(...*):?} */
var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location");

/** @type {function(...*):?} */
var ___stdio_exit = Module["___stdio_exit"] = createExportWrapper("__stdio_exit");

虽然在设置了Module 对象中的各种方法,但是并没有提供导出的功能,所以我们需要在这个文件的代码最下面,添加 一段代码

......
run();
// 以上为文件已有代码 

export default Module // 新增代码片段

这样的话就提供了一个对象供调用

  1. 编译出的文件除了js还有wasm文件,这个wasm文件是提供js文件调用的。

由于webpack不能处理.wasm后缀的文件,所以我们需要将 .wasm文件放在 public/js 中,方便项目打包后,js文件能够访问到 .wasm文件。

在 vue 项目中引用。

通过下面的方式引入.js 文件

import wasmModule from "@/utils/index.js"; //模块名称没有固定
  1. 在 methods 中调用方式如下

必须使用异步方式
调用的时候,在js中需要使用 下划线+编译命令执行时设置导出的某个函数名: 例如 _setSeed

async functionName (){
    const instance = await wasmModule; 
    
    instance._exchangeCoordinate(params1,params2,...otherparams)
}

上面的 _exchangeCoordinate 就是调用了 .cpp文件 中的 exchangeCoordinate 函数。
以上就是处理如何在vue项目中调用 cpp提供的函数。

分割线
我之前在网上找了很多类似的内容,发现类似以下的内容

async function waitwasm() {
  const wasmmodule = await OriginalVueWasm;
  wasmmodule.default.onRuntimeInitialized = () => {
    Vue.prototype.$wasm = wasmmodule.default;
    //new Vue ...
  }
}
(async () => {
  waitwasm()
})()

我也按照这样引入的,但是我把 wasmmodule 打印出来之后,他包含一个 default 属性,这个属性包含了很多方法,包括了要导出的模块,但是我并没有发现其中有onRuntimeInitialized事件。而且通过 this.$wams 去访问里面的 _funtionName 会报错。
有任何问题的话,欢迎在评论区交流讨论~~~~~~~~~~~~~~~~

Logo

前往低代码交流专区

更多推荐