光谷码农 2017-08-31
参考网站:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly
http://kripken.github.io/emscripten-site/
WebAssembly是实验性代码,为.wasm后缀二进制文件,可以通过emcc将c/cpp编译成wasm文件,再通过WebAssembly.instantiate(bufferSource, importObject) 实现cpp与js的交互。
将cpp函数导出,其中一种方式是extern "C" {}包围
main.cpp 实现js调用cpp的随机函数生成器
#include<stdio.h> #include <random> #include <iostream> #include <atomic> #include <math.h> using namespace std; extern "C" { mt19937 engine; void setSeed(long seed) { engine.seed(seed); } double mtrandom() { double min = 0.0; double max = 1.0; uniform_real_distribution<double> distribution(min, max); double d = distribution(engine); return d; } }
使用emcc可以编译成纯js模式,或者wasm格式,这里编译出wasm文件
emcc main.cpp -o index.html -s EXPORTED_FUNCTIONS="['_setSeed','_mtrandom']" -s WASM=1
EXPORTED_FUNCTIONS 指定导出函数,WASM指定生成wasm格式
index.html
<!doctype html> <html lang="en-us"> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>js调用cpp函数例子</title> </head> <body> 种子:<input id="seedInput" type="number" value="123456" /><br> 数量:<input id="numInput" type="number" value="20" /><br> <button onclick="run1()" >cwrap调用</button><button onclick="run2()" >直接调用</button> <div id="log"> </div> <script type='text/javascript'> function run1() { var fun1=Module.cwrap('setSeed'); var fun2=Module.cwrap('mtrandom'); var seed=parseInt(seedInput.value); var num=parseInt(numInput.value); fun1(seed); log.innerHTML=""; for(var i=0;i<num;i++) { log.innerHTML+=fun2()+"<br>"; } } function run2() { var seed=parseInt(seedInput.value); var num=parseInt(numInput.value); _setSeed(seed);//全局函数 log.innerHTML=""; for(var i=0;i<num;i++) { log.innerHTML+=_mtrandom()+"<br>"; } } </script> <script async type="text/javascript" src="index.js"></script> </body> </html>
js调用cpp方法,一可以使用cwarp方法,二可以使用下划线_加cpp函数名