在 WebAssembly 中实现回调的方式
本文将介绍在 C++ 中实现 js 回调的几种方式. 在使用 wasm 的过程中, 避免不了要从 C++ 回调 js 的函数来实现异步交互.
官网文档 https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#
中已经介绍了6种实现回调的方式, 这里介绍几种能解决实际问题的方式。
#EM_ASM 相关参数介绍
EM_ASM 函数簇包含
EM_ASM
EM_ASM_INT
EM_ASM_DOUBLE
类似的使用方式 :
EM_ASM_({
postMessage({cmd: 'callback', text: "callback", threadId: $2, callId : $0, code : $1})
}, callback, code, tid);
其中$0$1$2分别代表 callback, code, tid 的值.
后面两个函数还可以获取到 js 返回的 int/ double 值. 一般能满足简单的使用.
#如何在 worker 中实现回调
使用 wasm 的时候, 某些任务会被放到 worker 中执行, 执行完成后回调通知结果.
这个时候要特别注意: worker 和主线程是相互独立的, 并不能像普通的多线程可以共享进程内的数据. 在 worker 中调用 js 回调时, 第一个面临的限制就是 web worker 的限制:
- 不能访问 window, document 对象
- 与主线程通信需要通过 post message 方式
- 不能访问主进程中的全局变量会对象
如果直接在 worker 中直接调用回调, 就只能做一些简单的事情. 为此 emscripten 提供了以下函数:
MAIN_THREAD_EM_ASM
MAIN_THREAD_EM_ASM_INT
MAIN_THREAD_EM_ASM_DOUBLE
MAIN_THREAD_ASYNC_EM_ASM
顾名思义就是在主线程中执行函数. 但是前面 3 个函数不管在哪个线程调用都会会阻塞主线程.
推荐使用最后一个 MAIN_THREAD_ASYNC_EM_ASM, 区别就是在如果是主线程调用该函数,会被理解执行,如果是在其他线程调用,则会被追加到主线程的任务队列再被执行.
至于如何实现这个功能了, emscripten 也突破不了这个限制, 也是通过 postMessage 的通信机制实现的.
在不熟悉 emscripten 的时候我自己模拟了这个过程:
- 在主线程注册函数, 保存在一个特定的对象中, 并产生一个 callid
- 把callid 传到 worker 中,使用上述的 EM_ASM 回调
- 子线程会把信息 post 到主线程
- 主线程收到 message 和 callid, 去特定的对象查找到已经注册的回调函数, 执行函数,完成回调
#如何在回调中传递字符串
在 emscripten 值的传递, 除了基本类型是通过拷贝的, 字符串和数组,内存都是通过指针地址去传递.
std::string data = "{\"code\" : 0, \"msg\" : \"/input.mp4\"}"
MAIN_THREAD_ASYNC_EM_ASM({
var dataStr = UTF8ToString($0);
console.log(dataStr)
}, data.c_str());
在回调函数中,通过 UTF8ToString 函数把传递过去的指针转成 js 的字符串, 这样来达到传递字符串的目的.
在 WebAssembly 中实现回调的方式的更多相关文章
- C语言学习及应用笔记之七:C语言中的回调函数及使用方式
我们在使用C语言实现相对复杂的软件开发时,经常会碰到使用回调函数的问题.但是回调函数的理解和使用却不是一件简单的事,在本篇我们根据我们个人的理解和应用经验对回调函数做简要的分析. 1.什么是回调函数 ...
- PHP中的回调函数和匿名函数
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- 理解和使用 JavaScript 中的回调函数
理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报 分类: JavaScript(4) 目录( ...
- [转]理解与使用Javascript中的回调函数
在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...
- 【JavaScript】理解与使用Javascript中的回调函数
在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...
- JQuery中的回调对象
JQuery中的回调对象 回调对象(Callbacks object)模块是JQuery中的一个很基础的模块,很多其他的模块(比如Deferred.Ajax等)都依赖于Callbacks模块的实现.本 ...
- Java中的回调
又忙了一周,事情差不多解决了,终于有可以继续写我的博客了(各位看官久等了). 这次我们来谈一谈Java里的一个很有意思的东西--回调. 什么叫回调,一本正经的来讲,在计算机程序设计中,回调函数是指通过 ...
- 浅析android系统设计中的回调思想
一.为何写作本文 在慢慢深入接触android开发的过程中,我越来越发现android中(至少应用曾的开发)用到了很多回调的思想.比如activity的生命周期,fragment的生命周期,皆是回调 ...
- 【Java入门提高篇】Day4 Java中的回调
又忙了一周,事情差不多解决了,终于有可以继续写我的博客了(各位看官久等了). 这次我们来谈一谈Java里的一个很有意思的东西——回调. 什么叫回调,一本正经的来讲,在计算机程序设计中,回调函数是指通过 ...
随机推荐
- 编写通用的Makefile
一个应用程序的形成是少不了一下几个步骤的. 1. 预处理 #检查语法错误.包含头文件.展开#if.#define等宏定义 2. 编译 #把.c文件转换为汇编文件.s 3. 汇编 #把.s汇编转换为机器 ...
- 1.简单使用两片74HC595实现动态显示数码管
本篇文章主要是讲解如何简单示用74HC595,更具体的讲解请移步 https://www.cnblogs.com/lulipro/p/5067835.html#undefined 这篇文章讲解的更加详 ...
- 【NC基础操作】开发环境配置初体验
当我们拿到开发工具UAP-STUDIO-6.5.0.2和Home文件的时候,意味着我们可以用这两样东西开始进行项目开发了(默认其他准备已就绪). 运行UAP-STUDIO-6.5.0.2 双击进入&q ...
- Hadoop集群安装配置
一.准备工作 1.首先准备好七台虚拟机,并确保都已经安装配置好jdk. 2.Hadoop3.2.0+jdk1.8自行到官网下载 3.修改好相称的主机名,并在hosts文件中相互添加. ######注意 ...
- gcc/g++命令参数
在windows环境下,我们运行一程序,只需要在VS中点击运行按键即可,VS帮我们做完了程序的预处理.编译.汇编.链接阶段 但是在linux环境下,我们只能借助gcc/g++完成这一系列的操作 -o参 ...
- 壁球小游戏详解(附有源码.cpp)
1.在python中安装pygame 2.将下列源码复制过去,运行. #引用 import pygame, sys #初始化 pygame.init() size = width, height = ...
- 使用Pr压缩视频,增大音量
视屏压缩(亲测有效教程):https://www.zhihu.com/question/67762625 音量增大(亲测有效教程):https://jingyan.baidu.com/article/ ...
- SpringBoot初识日志
SpringBoot初识日志 1.市面上的日志框架: JUL.JCL.Jboss-logging.logback.log4j.log4j2.slf4j- 日志门面(日志的抽象层) 日志实现 SLF4j ...
- Python绘制雷达图(俗称六芒星)
原文链接:https://blog.csdn.net/Just_youHG/article/details/83904618 背景 <Python数据分析与挖掘实战> 案例2–航空公司客户 ...
- 【MySQL】MySQL知识图谱
MySQL 文章目录 MySQL 表 锁 索引 连接管理 事务 日志系统 简单记录 极客时间 - MySQL实战45讲 MySQL知识图谱 表 表 引擎选择 编码问题 表空间管理 字段设计 备份和恢复 ...