系列文章目录

第一章 WebAssembly概念
第二章 Emscripten详解
第三章 JavaScript调用C\C++
第四章 C\C++调用JavaScript


WebAssembly第三章 JavaScript调用C\C++

  • 系列文章目录
  • 前言
  • 我的环境
  • 一、码代码
    • 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

一、码代码

JavaScript载入并运行WASM

目标

在Emscripten提供的迷你HTML模板页面上通过运行C++生成的wasm显示helloworld字样。
载入wasm的话,如果源文件有main函数就会自动运行。

先用C++写个hello world

sayhello.cpp

#include <stdio.h>
#include <iostream>using namespace std;int main(int argc, char ** argv) {printf("我是printf: Hello World\n");cout<<"我是C++的cout "<<"你好,世界"<<endl;return 0;
}

编译

 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 <stdio.h>
#include <iostream>
#include <emscripten/emscripten.h>
using namespace std;int main(int argc, char ** argv) {printf("我是printf: Hello World\n");cout<<"我是C++的cout "<<"你好,世界"<<endl;return 0;
}#ifdef __cplusplus
extern "C" {#endifvoid EMSCRIPTEN_KEEPALIVE myFunc1()
{printf("我的函数已被调用\n");return;
}int EMSCRIPTEN_KEEPALIVE myFunc2(int a, int b)
{printf("a+b=%d\n", a+b);return a+b;
}#ifdef __cplusplus
}
#endif

__cplusplus用于探测是否C++环境
EMSCRIPTEN_KEEPALIVE是Emscripten特有的宏,用于告知编译器后续函数在优化时必须保留,并且该函数将被导出至JavaScript


编译sayhello.cpp

docker 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标签内加入

<button class="mybutton">运行我的函数</button>

在script段加入按钮click事件监听。

document.querySelector('.mybutton').addEventListener('click', function(){alert('检查控制台');var result = Module.ccall('myFunc1', // name of C functionnull, // return typenull, // argument typesnull); // argumentslet 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等)。

WebAssembly第三章 JavaScript调用C\C++ 关键字:wasm emcc js c++ c相关推荐

  1. 03前端第三章Javascript

    html是网页内容(骨架),css是网页样式(皮肤),JavaScript是网页行为(动作). JavaScript概述 JavaScript一种直译式脚本语言,用来为网页添加各式各样的动态功能 (j ...

  2. 第三章JavaScript 内置对象

    1 Number 1.1 属性 MAX_VALUE JS可以表示的最大的数字 MIN_VALUE JS可以表示的最小的数字 1.2 方法 toFixed(length) 指定保留长度的小数 toExp ...

  3. JavaWEB三:Javascript

    Javascript 简介 起源 在1995年时,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成.Netscape在最初将其脚本语言命名为LiveScript, ...

  4. “JavaScript patterns”中译本 - 《JavaScript 模式》第三章

    第三章 直接量和构造函数 JavaScript中的直接量模式更加简洁.富有表现力,且在定义对象时不容易出错.本章将对直接量展开讨论,包括对象.数组和正则表达式直接量,以及为什么要使用等价的内置构造器函 ...

  5. 《学习JavaScript数据结构与算法》第三章 数组

    文章目录 前言 一.创建 && 初始化数组 二.操作数组 push-添加元素于末尾 unshift-添加元素于开头 pop-从数组末尾开始删除元素 shift-从数组开头开始删除元素 ...

  6. javascript进阶课程--第三章--匿名函数和闭包

    javascript进阶课程--第三章--匿名函数和闭包 一.总结 二.学习要点 掌握匿名函数和闭包的应用 三.匿名函数和闭包 匿名函数 没有函数名字的函数 单独的匿名函数是无法运行和调用的 可以把匿 ...

  7. JavaScript Dom编程艺术(第二版)读书笔记 第三章DOM

    第三章DOM 3.1文档中的DOM的"D" 如果没有document(文档),DOM也就无从谈起.当创建了一个网页并把它加载到Web浏览器中时,Dom就在幕后悄然而生.它把你编写的 ...

  8. JavaScript高级编程设计(第三版)——第三章:基本概念

    系列文章目录 第二章:在html中使用javaScript 第三章:基本概念 第四章:变量作用域和内存问题 目录 系列文章目录 前言 一.语法 1.标识符 2.关键字和保留字 二.数据类型 1.nul ...

  9. Javascript面向对象编程指南笔记 - 第三章 - 函数

    第三章 函数 第三章 函数 3-1 什么是函数 3-1-1 调用函数 3-1-2 参数 3-2 预定义函数 3-2-1 parseInt 3-2-2 parseFloat 3-2-3 isNaN 3- ...

最新文章

  1. 高并发:RocketMQ 削峰实战
  2. python datetime计算时间差_Python中关于日期的计算总结
  3. 结构体字节对齐(转)
  4. spss非线性回归分析步骤_SPSS与简单线性回归分析
  5. poj2115C Looooops
  6. Win10系统怎么锁定IE浏览器主页
  7. Excel中如何在打印时自动给每行加上标题
  8. Windows Phone 数据库并行访问【转】
  9. 解决办法:ImportError: No module named google.protobuf.internal
  10. 算法:Maximum Depth of Binary Tree(二叉树的最大深度)
  11. 浅谈JS各种宽高(clientHeight、scrollHeight、offsetHeight等)
  12. MFC Windows 程序设计[二十一]之树形控件
  13. itest(爱测试) 4.3.1 发布,开源BUG 跟踪管理 amp; 敏捷测试管理软件
  14. K8s 开先河、技能全栈、业务“无感”,深度解读云原生的这一年
  15. 如何利用 C# 爬取「财报说」中的股票数据?
  16. 工作流待办事项消息提醒
  17. 【面试智力题】一楼到十楼的每层电梯门口都放着一颗钻石,钻石大小不一。你乘坐电梯从一楼到十楼,怎样拿到最大的一颗?
  18. Word里面怎么才能输入平方
  19. 空气净化器什么牌子好,家用空气净化器哪个牌子好推荐
  20. [Themeda启动器]用Java编写的Minecraft启动器

热门文章

  1. vue+webpack打包发布到线上后微信公众号H5部分打开白屏,刷新又好了
  2. MAC环境下Eclipse Android jni环境配置
  3. 字符编码之ASCII编码
  4. 使用Altium Designer 绘制原理图并且使用STM32F103完成对SD卡的数据读取
  5. 从入门到精通ARM(4412)-Linux内核驱动编程【下】-李志勇-专题视频课程
  6. catkin工作区 各文件夹功能
  7. vue+echarts实现动态绘制图表及异步加载数据的方法
  8. 资源 | Python数据分析课程:从入门到实战
  9. O2O助汪峰成功逆袭,汪峰终于上头条了
  10. MacOS磁盘目录结构