第一章 WebAssembly概念
第二章 Emscripten详解
第三章 JavaScript调用CC++
第四章 CC++调用JavaScript
WebAssembly第三章 JavaScript调用CC++
- 系列文章目录
- 前言
- 我的环境
- 一、码代码
- JavaScript载入并运行WASM
- 目标
- 先用C++写个hello world
- 编译
- 游览器查看结果
- JavaScript调用C++函数
- C++代码
- 编译sayhello.cpp
- 编辑helloworld2.html
- ccall函数签名
- 运行结果
- 总结
前言
本篇是WebAssembly系列文章的第三章,我会在本文介绍在几个常用场景下JavaScript调用C++函数所需要用到的操作步骤,编译命令,和具体的代码。
我的环境
| 组件 | 版本 |
|---|---|
| CentOS | 7 |
| Docker | 20.10.7 |
| emscripten/emsdk | 3.1.14 |
| nginx | 1.18.0 |
| chrome | 102.0.5005.115 |
在Emscripten提供的迷你HTML模板页面上通过运行C++生成的wasm显示helloworld字样。
载入wasm的话,如果源文件有main函数就会自动运行。
sayhello.cpp
#include#include using namespace std; int main(int argc, char ** argv) { printf("我是printf: Hello Worldn"); cout<<"我是C++的cout "<<"你好,世界"< 编译 docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emcc sayhello.cpp -s WASM=1 --shell-file templates/shell_minimal.html -o helloworld.html将生成的js,wasm,html文件发布到部署到web服务器。
游览器查看结果 JavaScript调用C++函数这里我们用C++写一个无参函数和一个有两个参数的函数,来展示下如果在JavaScript端使用它们。
C++代码代码如下(示例):
sayhello.cpp#include#include #include using namespace std; int main(int argc, char ** argv) { printf("我是printf: Hello Worldn"); cout<<"我是C++的cout "<<"你好,世界"< #endif void EMSCRIPTEN_KEEPALIVE myFunc1() { printf("我的函数已被调用n"); return; } int EMSCRIPTEN_KEEPALIVE myFunc2(int a, int b) { printf("a+b=%dn", a+b); return a+b; } #ifdef __cplusplus } #endif __cplusplus用于探测是否C++环境
EMSCRIPTEN_KEEPALIVE是Emscripten特有的宏,用于告知编译器后续函数在优化时必须保留,并且该函数将被导出至JavaScript
编译sayhello.cppdocker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emcc --std=c++11 sayhello.cpp -s WASM=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']" --shell-file templates/shell_minimal.html -o helloworld2.html编辑helloworld2.html给页面增加个按钮来手动触发调用函数。
在body标签内加入在script段加入按钮click事件监听。
document.querySelector('.mybutton').addEventListener('click', function(){ alert('检查控制台'); var result = Module.ccall('myFunc1', // name of C function null, // return type null, // argument types null); // arguments let myfuncResult = Module.ccall('myFunc2', 'number', ['number', 'number'], [1,2]); console.log('myFunc2 result = '+myfuncResult); });ccall函数签名var result = Module.ccall(ident, returnType, argTypes, args);
参数:
ident :C导出函数的函数名(不含“_”下划线前缀);
运行结果 总结
returnType :C导出函数的返回值类型,可以为’boolean’、‘number’、‘string’、‘null’,分别表示函数返回值为布尔值、数值、字符串、无返回值;
argTypes :C导出函数的参数类型的数组。参数类型可以为’number’、‘string’、‘array’,分别代表数值、字符串、数组;
args :参数数组。以上就是今天要讲的内容,本文仅仅简单介绍了JavaScript调用C++ WASM的使用,而关于Emscripten一些更详细的内容在系列文章其它章节提供(例如:module,编译命令详解,C++调用web api等)。



