IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> WebAssembly第三章 JavaScript调用C |C++ 关键字:wasm emcc js c++ c -> 正文阅读

[C++知识库]WebAssembly第三章 JavaScript调用C |C++ 关键字:wasm emcc js c++ c

系列文章目录

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



前言

本篇是WebAssembly系列文章的第三章,我会在本文介绍在几个常用场景下JavaScript调用C++函数所需要用到的操作步骤,编译命令,和具体的代码。


我的环境

组件版本
CentOS7
Docker20.10.7
emscripten/emsdk3.1.14
nginx1.18.0
chrome102.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" {
#endif

void 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 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等)。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:02:42  更:2022-07-17 16:04:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/11 18:41:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码