在 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里的一个很有意思的东西——回调. 什么叫回调,一本正经的来讲,在计算机程序设计中,回调函数是指通过 ...
随机推荐
- ROS代码经验系列-- tf进行位置查询变换
include文件: #include "tf/transform_broadcaster.h" #include "tf/transform_listener.h&qu ...
- react项目中登陆注册验证码的倒计时,页面刷新不会重置
目前很多的网站和app在做登陆注册时都会用到手机验证码,为了防止验证码轰炸,也就是随意的点击验证码,一般我们需要对获取验证码进行一些限制,最常用到的是在规定时间内不得重复发送. 实现倒计时很简单,可以 ...
- node-sass 安装失败报错的原因及解决办法(整理)
npm install 时偶尔遇到报错:没有安装python或node-sass 安装失败的问题,百度之后发现是被墙了,但根据百度的方法换了淘宝镜像和用了vpn都安装失败,最后发现原来是因为没有卸载之 ...
- mysql8.0.19压缩版安装
1.官网下载.zip格式的MySQL Server的压缩包,选择x86或x64版,并解压. 2. 创建 data文件夹 及 my.ini文件,并编辑 [mysqld] # 设置为自己MYSQL的安装目 ...
- jpa 主键重复导致查询list的数据总是重复第一条数据
背境: JPA 读取 Oracle 中的视图,同一条sql, 在数据库 IDE (PLSql)读出 878 条记录并正常显示,代码依然保存了 878 条记录,但所有记录均一样,即数据库中第一条记录. ...
- 总结(2019CSP之后),含题解
从\(\mathcal{CSP}\) 爆炸 到现在,已经有\(3\)个月了.这三个月间,我--这个小蒟蒻又接触了许多听不懂的东西 \(\mathcal{No.}1\) 字符串\(\mathcal{ha ...
- 使用Lists.partition切分性能优化
项目实战 影拓邦电影同步中,使用Lists.partition按500条长度进行切分,来实现es的同步. 切分的List为 使用介绍及示例 将list集合按指定长度进行切分,返回新的List<L ...
- Facetoprocess_program_design
面向过程程序设计 程序:计算机用可理解可执行的命令的集合. 过程:问题解决的步骤. 方法(函数) 结构化程序设计的基础 一.方法三要素 1 功能: 实现的功能(单一).简单.易维护 2 参数: (传入 ...
- Python基础(下篇)
本篇文章主要内容:异常处理,函数,模块和包. 在开始正篇之前我们先来看看上一篇可乐留下的题目. 题目: 变量 a= {"name": "可乐", "a ...
- ThreadX移植——STM32H7+MDK-AC6平台
作者:zzssdd2 E-mail:zzssdd2@foxmail.com 一.前言 在uCOS全家桶宣布开源之后被微软收购的ThreadX也开源了,真是喜大普奔,对于我们这些嵌入式行业从业者来说,能 ...