【问题标题】:How to detect browser information from WebAssembly module?如何从 WebAssembly 模块中检测浏览器信息?
【发布时间】:2020-01-17 16:05:31
【问题描述】:
如何从启动时通过 JavaScript 检测到的值(如当前的 screen.availWidth)启动 C++ 变量(编译为 WebAssembly)?
此代码需要从 WebAssembly 模块启动,因此用户不能注入与真实值不同的值。
【问题讨论】:
标签:
javascript
c++
browser
webassembly
emscripten
【解决方案1】:
说明
您可以从 C++ 函数内部运行 JavaScript 代码。此类 JS 代码可以访问您在 Web 浏览器中运行时通常可以访问的所有对象。为此,我们将使用 EM_ASM_INT 宏来执行返回 int 值的 JS 代码。
快速解决方案
我们将 JS 代码注入到 C++ 代码example.cpp 中。使用int main() 函数可以确保代码在加载页面时自动执行,无需手动加载 WebAssembly 模块。但是,您也可以使用不同的函数,将其导出并在您的网页上执行。
#include <iostream>
#include <emscripten.h>
int main()
{
int screen_width = EM_ASM_INT(
return screen.availWidth;);
std::cout << "Screen width=" << screen_width << std::endl;
}
我们用Emscripten compiler编译上面的example.cpp代码如下:
emcc example.cpp -o example.html
输出是一个嵌入了int main()函数的网页,里面有JS代码(真的,inception)。
要在允许跨域资源共享 (CORS) 的同时运行代码,我们将使用 emrun 工具(我无法在 Firefox 上运行该示例,因此我使用了 Chrome):
emrun --browser chrome example.html
评论
此方法适用于返回值类型为标量int(使用EM_ASM_INT)、double(使用EM_ASM_DOUBLE)的JS 代码,也适用于char* 数组(使用EM_ASM_INT,请谨慎使用和手动内存管理如图here)。