我阅读了https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API和http://webassembly.org/docs/js/,似乎我找到了从 wasm 调用 Javascript 函数的所有示例是用受 LISP 启发的语法编写的。
是否可以使用 emscripten C 在 wasm 中导入 JS 函数?
尝试遵循 emscripten 教程,在对 emscripten 的 C 调用之间传递参数,但仅正确传递数字,而不传递字符串。如何从 js 库调用将字符串返回到 C?
测试.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <emscripten.h>
extern char *getText(void);
int main() {
printf(getText());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
mylib.js:
mergeInto(LibraryManager.library, {
getText: function() {
return "a test string";
}
});
Run Code Online (Sandbox Code Playgroud)
构建命令:
emcc test.c -o test.html --js-library mylib.js
Run Code Online (Sandbox Code Playgroud)
我期望看到的输出是“测试字符串”,但我实际看到的是“emcc”
我在 stackoverflow 和其他地方进行了广泛的查找,但是我找不到任何关于将字符串值从 JS 返回到 C 的信息,只能找到将它们从 C 传递到 JS 的信息,所以这不是我能找到的任何其他问题的重复。
是什么赋予了?
我想在 docker 环境中使用 headless chrome 来运行编译为 Web 程序集的 C++ 测试。
我已确保我的测试可执行文件与--emrun标志链接,以确保所有输出都发布到 emrun 服务器并打印到控制台(然后由 CTest 框架捕获)。
但是,当运行无头铬时
emrun --browser=chrome --browser_args="--no-sandbox --disable-gpu --use-gl=swiftshader --headless" ./MyTestExecutable.html --gtest_filter=MyTestFixture.myTest
Run Code Online (Sandbox Code Playgroud)
没有任何内容打印到输出中。但是,如果我将命令更改为
emrun --browser=chrome --browser_args="--no-sandbox --disable-gpu --use-gl=swiftshader --headless --remote-debugging-port=9222" ./MyTestExecutable.html --gtest_filter=MyTestFixture.myTest
Run Code Online (Sandbox Code Playgroud)
测试输出很高兴地打印到命令行,但如果输出超过 cca 9kB,则会被截断,这是它自己的问题 - 见下文。但是,chrome 调试会话保持挂起并使用端口 9222。我当前的解决方法是确保 CTest 框架中的每个单元测试都有自己独特的调试端口,并让 chrome 会话保持生成状态,直到容器停止 - docker 清理它们那就起来吧。这个解决方案很脏,我不喜欢它。
--remote-debugging-port我想知道是否有人知道如果没有提供给 Chrome,为什么 emrun 服务器不会打印任何内容?
我的预感是,chrome 在完成执行后会停止向 emrun 服务器发送数据,并且启用调试会以某种方式减慢 chrome 的速度,从而为至少一些输出发送到 emrun 服务器腾出时间(这也解释了大输出大小的截断) 。
我还去查看了 Emscripten 人员如何运行他们的 CI 测试,发现他们在 Xvfb 下使用完整的 chrome,而不是 headless chrome。我也尝试过,但是,这导致了一些其他问题,例如如果在容器内运行但不是以 root 用户身份运行,则 chrome 会因 SIGTRAP 崩溃,而 …
我正在使用 Emscripten 将一些 C 代码编译为 WebAssembly。这是我的 Makefile 中的最后一个 emcc 调用:
emcc $(CFLAGS) iva.a -o iva.js
Run Code Online (Sandbox Code Playgroud)
它按预期工作并生成 .js 文件和 .wasm 文件。JS 加载到我的 HTML 页面中,如下所示:
<script src="../dist/iva.js">
Run Code Online (Sandbox Code Playgroud)
它会正确加载并实例化 WebAssembly 代码iva.wasm。加载页面后不久,此消息就会出现在控制台中:
Fetch finished loading: GET "http://localhost:6931/dist/iva.wasm".
Run Code Online (Sandbox Code Playgroud)
我认为这意味着我的 WebAssembly 是通过 fetch() 加载的,也许在等待一些处理时,我可以通过控制台访问我的函数:
Module._init_display_system()
Run Code Online (Sandbox Code Playgroud)
并获取返回值。这是正确的并且一切正常。
显然,我也应该能够通过脚本来做到这一点。但是,我看不到一种仅在实例化 WebAssembly后运行函数的方法。我感觉我错过了一些相当明显的东西。
无论如何,我该怎么做?
我已经通过 emscripten 使用 WASM 几个星期了,并且取得了良好的进展,直到出现此错误:
exception thrown: RuntimeError: function signature mismatch,RuntimeError: function signature mismatch
Run Code Online (Sandbox Code Playgroud)
这种情况开始发生在以前可以工作的代码中,似乎与 WASM 缺乏对 javascript 中 64 位整数的支持以及文件管理中使用的偏移量有关。我做了一个孤立的案例:
#include <iostream>
int main(int argc, char const *argv[])
{
char test[30];
std::cout << __LINE__ << std::endl;
FILE *f = fopen("minimal_call_dispatch.cpp","ra");
std::cout << __LINE__ << std::endl;
fseek(f, 100, SEEK_SET);
std::cout << __LINE__ << std::endl;
fclose(f);
std::cout << __LINE__ << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
建筑:
call emcc -o ./test.js test_file.cpp -s WASM=1 -s NO_EXIT_RUNTIME=1 -std=c++1z
Run Code Online (Sandbox Code Playgroud)
由于上述错误,在“fseek”失败之前会输出“6\n8\n”。
在此过程中,我怀疑 wasm 正在尝试使用与具有 64 位整数而不是 …
我正在运行一个使用 emscripten 编译为 wasm 的 C 工具。该工具适用于非常大的文件。在 CLI 上正常运行此工具时,通常操作会传输结果并在返回足够的数据后提前终止程序。例如你可以运行:
./tool <input-file> | head -n 100
该工具将在检测到 stdout 已被 关闭后终止head,实际上仅读取一小部分输入。
问题是带有 emscripten 的 stdout 似乎是异步的(通过覆盖 Module.print),因此该工具每次都会运行完成。有没有办法让它在标准输出上阻塞,这样我只能读取我需要的内容,然后终止该工具?
通过使用以下选项进行编译,
emcc -s WASM=1 main.cpp -o index.js
emscripten 生成一个index.wasm, 和一个 js 包装器index.js。js 包装器在浏览器中运行时加载.wasm位于同一目录中的文件。XMLHttpRequest
那么如果我需要手动加载文件该怎么办呢.wasm?加载部分似乎是硬编码在包装器中的。
以下是我需要这样做的一些情况:
.wasm从另一个 url(例如从 CDN)提供该文件。.wasm是动态生成的。XMLHttpRequest不允许的沙箱中运行,只有像getMyData('some_file')..wasm我知道我只能通过以下方式生成文件
emcc -s WASM=1 main.cpp -o index.wasm
但随后我丢失了包装器,这在使用 SDL 和 GLES 等 emscripten API 时并非易事。
在本教程中,它展示了以下导出 C 函数的示例
./emcc tests/hello_function.cpp -o function.html -s EXPORTED_FUNCTIONS='["_int_sqrt"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
Run Code Online (Sandbox Code Playgroud)
我想做同样的事情,除了我像这样使用 CMake
cd bin
emcmake cmake ../src
emmake make
Run Code Online (Sandbox Code Playgroud)
emmake 中指定的规范方式是什么-s?我应该添加它来CMakeLists.txt喜欢吗
set(EXPORTED_FUNCTIONS '["_int_sqrt"]')
Run Code Online (Sandbox Code Playgroud)
或者做类似的事情?
我按照本指南使用emsdk$PATH安装了 emscripten 并激活了它。然后我按照 emsdk 本身的指示配置了我的文件并获取了源。现在我可以在终端中emsdk-master/emsdk_env.sh访问emcc和。该文件也存在(这是 QtCreator 将生成的文件) fetch 来查找 WASM 编译器的路径)。em++~/.emscripten
Qt 的套件WebAssembly也已由 Qt 安装Maintenance Tool。
现在,在 QtCreator 的套件配置中,我得到了这个(QtCreator 在采购后通过终端打开emsdk_env.sh):
它本身无法确定编译器的路径。
在“编译器”选项卡中,我手动添加了一个编译器,如下所示:
但之后我在“套件”选项卡中收到此错误:
这意味着什么?我跳过了什么?有人有这样做的经验吗?
另外,将编译器从 更改em++为wasm-32-wasi-clang++或clang++不会改变任何内容。
顺便说一句,如果我使用该套件,我会得到:
Error while parsing file whatever.pro. Giving up.
Project ERROR: Cannot run target compiler 'em++'. Output:
===================
===================
Maybe you forgot to setup the environment?
Run Code Online (Sandbox Code Playgroud)
请不要告诉我这个问题是这个 …
我正在尝试使用一些 ES 3.1 功能,目前尚不清楚是否支持:
我注意到 emscripten 存储库中有一个 OpenGL ES 3.1 标头,它定义了我正在寻找的一些函数,我可以将它们成功地包含在我的项目中。但是,当我尝试链接时它们不可用:
error: undefined symbol: glDispatchCompute (referenced by top-level compiled C/C++ code)
warning: _glDispatchCompute may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
Run Code Online (Sandbox Code Playgroud)
文档说,如果我指定(我正在这样做),则支持 OpenGL ES3 。-s FULL_ES3=1
既然有它的标题,那么这个功能可用吗?如果是这样,我如何启用对其的支持?(例如,是否需要手动加载扩展或在 emscripten 中启用实验支持?)
emscripten ×10
webassembly ×6
javascript ×3
c ×2
c++ ×2
cmake ×1
docker ×1
emmake ×1
headless ×1
linux ×1
mismatch ×1
opengl-es ×1
qt ×1
qt-creator ×1
webgl ×1
webgl2 ×1