在 Emscripten C++/wbasm 中,如何获得“页面关闭”事件
Posted
技术标签:
【中文标题】在 Emscripten C++/wbasm 中,如何获得“页面关闭”事件【英文标题】:In Emscripten C++ / wbasm how does one get an "on page closed" event 【发布时间】:2018-11-28 20:25:12 【问题描述】:我有使用 emscripten 系统编译成 Web 程序集的 C+ 程序。当他运行程序的页面关闭时,我想清理一些东西,刷新文件等。
主要有:
emscripten_set_main_loop_arg(onMainLoopTick, arg, 0, 1);
目前,当页面关闭时,“进程”只是简单地退出,并且在“循环模拟器”之后不会继续。我想我需要从页面中获取一个事件,该事件将阻塞主线程,直到 C++ 代码处理它并清理它的混乱。
我应该将什么事件转发给 C++,我应该如何使用它?
【问题讨论】:
你的意思是当页面关闭时你想要类似 atexit() 或 SIGINT 处理程序? @BumsikKim 在功能上是的,但是在浏览器环境中不受支持。我假设我必须在主线程上订阅一个事件并将其传递给 C++ 代码或提供一个回调到罐装 emscripten 提供的方法,但我找不到关于关机/睡眠/等序列的文档。 【参考方案1】:首先要知道的是,没有用于 WebAssembly 的本机库或 API(我的意思是……但是,as of MVP. There are native features like threads coming as post-MVP feature)。这意味着所有 C++ 中的系统库都是通过导入模拟的 javascript 函数来实现的。因此,如果您正在寻找诸如检测关闭事件之类的原生功能,您应该检查是否有 JS/html5 API 可以执行类似的操作。
要查看它是如何工作的,请打开生成的 .wast
文件并搜索 import
instructions 和生成的 JS 文件。此外,您可能想直接搜索 Emscripten repo 以检查 C++ 端是否有可用的 JS/HTML5 绑定,因为它们的文档很大且难以查看。
言归正传,关闭时触发的 HTML5 事件是 beforeunload
和 unload
。我更喜欢使用beforeunload
事件。 Emscripten 提供em_beforeunload_callback
回调函数类型和emscripten_set_beforeunload_callback
在html5.h bindings 中注册。
否则,您直接使用它们。例如:
在 C++ 中:
void EMSCRIPTEN_KEEPALIVE clean_stuff()
// Clean up the mess...
// You should use EMSCRIPTEN_KEEPALIVE or
// add it to EXPORTED_FUNCTIONS in emcc compilation options
// to make it callable in JS side.
在 JS 中:
window.addEventListener("beforeunload", function (event)
// Exported functions are prefixed by an underscore
Module._clean_stuff();
);
【讨论】:
是的,我知道这一点,但想知道 EMSDK 是否已经设置了执行此操作的固定功能和/或此处有“官方推荐的”最佳实践。他们的 (js) 代码已经为一些 dom 对象添加了监听器。我在我们的代码中实现了一个导出函数,并在 DOM 窗口上放置了 JS 侦听器以进行卸载和 beforeunload,并在任何 EMSDK 插入侦听器之前首先添加侦听器并得到我需要的东西。到目前为止(手指交叉)非常好。 :) @peterk 是的,虽然 EMSDK 有 html5.js,正如我所提到的,但我会像你一样自己添加监听器。根据我的经验,Emscripten 的文档几乎没有提出明确的“良好实践”或全面的示例,而且它的 API 似乎在没有通知的情况下发生了很大变化(尤其是在我自己设置“模块”对象时)。我可以理解,因为整个 Webassembly 生态系统还不稳定。至少他们的源代码在理论上并不复杂,所以很容易在源代码之后弄清楚他们的意图。以上是关于在 Emscripten C++/wbasm 中,如何获得“页面关闭”事件的主要内容,如果未能解决你的问题,请参考以下文章
通过 Emscripten 在 Javascript 中进行结构操作