有没有办法让Emscripten在Web工作者和主UI线程之间传输而不是复制数据?
Emscripten有一个管理Web Workers之间通信的API,我认为它只是使用了引擎盖下的postMessage/ onmessagemechanism.查看Emscripten Worker API的源代码,它似乎在调用时不使用该transferList选项postMessage,因此数据将被复制.
实际上,我认为它至少被复制了两次:首先是线程之间的浏览器,然后是Emscripten第二次将它复制到Emscripten管理的堆空间中.如果您希望数据在回调后继续在接收端生存,则必须第三次复制,因为根据文档,传递给回调的数据仅保证在回调期间存在.
从顶部重复我的问题:有没有办法让Emscripten通过在Web worker和主UI线程之间传输而不是复制数据来避免所有这些复制?
我目前正在开发一个个人的Node.js(> = 8.0.0)项目,它要求我调用C子程序(以改善执行时间).我正在尝试使用WebAssembly来执行此操作,因为我需要在浏览器中打开时最终代码兼容.
我使用Emscripten将C代码编译成WebAssembly,并且在此之后不知道如何继续.
任何正确方向的帮助都会很棒.谢谢!
从今天开始,有任何方法可以将本机JS脚本与从C ++代码(从Emscripten,chirp,clang-8 +等)生成的模块组合在一起,从而可以在重新使用模块的同时交换/修改脚本(即不必重新处理它们)在Node.js 和浏览器环境中都可以使用?
这句话很长-让我举个例子:
我想用JavaScript编写一些代码(例如测试代码),该代码使用fooC ++中实现的库(例如)。
我当前的(工作)设置如下所示:
浏览器
test1.js \
\
===(webpack)==> full.js
/
foo.cpp ==(emscripten)==> foo.js /
Run Code Online (Sandbox Code Playgroud)
Node.js:
foo.cpp ==(gcc/N-API)==> foo.node <--(require)-- test1.js
Run Code Online (Sandbox Code Playgroud)
浏览器方法的问题在于(AFAIK)每次修改/交换时我都必须重新运行WebPack test1.js才能将更改引入浏览器。
就我而言,运行webpack可能要花费很长时间,并且生成的构件相当大(10MB的倍数)。另外,我想在没有WebPack的相对较小的设备上运行代码,所以我什至每次都必须将这些工件传输到设备上。
因此,我现在想foo在一个地方(例如,在设备上)保留一个包含模块(无论如何看起来)的预处理工件,同时仅交换相对较小的本机JavaScript代码(test1.js)。(想象一下test*.js一个连续执行数百个文件的测试场景)
使用现代的浏览器/工具,ES6,ESM或您可以想到的任何方法-是否有办法为浏览器实现此目的?
奖励点是一个答案,它使我可以编写无需修改即可在Node.js 和浏览器中使用的代码。:)
抱歉:这是我什至不想使用WebPack时对此问题的修改,但现在我降低了期望。
我正在研究要编译为WASM并在浏览器中显示图像的C程序。该程序的重点是学习使用EGL进行设置,因此,我对涉及SDL,GLFW等的任何答案都不感兴趣。
此代码可将屏幕清除为蓝色(我省略了错误检查以减小尺寸):
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "emscripten.h"
struct Environment
{
EGLint majorVersion;
EGLint minorVersion;
EGLDisplay display;
EGLSurface surface;
};
static struct Environment g_env = {};
bool initGL(struct Environment* env)
{
env->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(env->display, &env->majorVersion, &env->minorVersion);
EGLint numConfigs = 0;
EGLint attribList[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
EGLConfig config;
eglChooseConfig(env->display, attribList, &config, 1, &numConfigs);
env->surface = eglCreateWindowSurface(env->display, config, 0, NULL);
static const …Run Code Online (Sandbox Code Playgroud) 我有一个 C++ 函数,它曾经被调用消耗来自 stdin 的输入。使用 emscripten 将此函数导出到 javascript 会导致调用 window.prompt。
与浏览器提示交互确实是一项乏味的任务。首先,您一次只能粘贴一行。其次,指示 EOF 的唯一方法是按“取消”。最后但并非最不重要的唯一方法(在我的函数的情况下)使其停止通过 window.prompt 要求用户输入是通过选中防止弹出更多提示的复选框。
对我来说,最好的输入方法是阅读一些 blob。我知道我可以破解 library.js 但我看到了一些问题:
最好的解决方案是某种回调,但我希望看到更有经验的用户的提示。
我正在使用 emscripten 编译一个 C 程序,该程序使用我编写的 JavaScript 库,并将它们与--js-library标志链接在一起。我的 C 代码调用库中的一个函数,其中有一个函数Promise,在回调中我希望它将给定的结果写入一些内存,该内存已从 C 调用者传递到 JS 函数中。这是一个例子(catch为了简洁,我省略了 Promise的错误捕获部分):
库.js
mergeInto(LibraryManager.library, {
compute_js: function(input, out_buf) {
do_promise_computation(
input
).then(function(result){
Module.print("Promise Returned fully");
for (var i = 0; i < 8; i++) {
var num = result[i]
{{{makeSetValue('out_buf+(i*4)', 0, 'num', 'i32')}}}
}
});
}
Run Code Online (Sandbox Code Playgroud)
程序.c
#include <stdio.h>
#include <stdint.h>
#include <emscripten.h>
extern void compute_js(int32_t, int64_t*);
int main() {
int32_t input = 1234;
int64_t out_buf[4];
int64_t* out_ptr = (int64_t*)(&out_buf);
printf("Calling Javascript\n"); …Run Code Online (Sandbox Code Playgroud) Emscripten 文档 ( https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#与代码直接函数调用交互)。
但是按值传递结构呢?如果我有这样的 C 函数:
typedef struct {double a, b, c;} MyStruct;
MyStruct Foo(const MyStruct x, double y);
Run Code Online (Sandbox Code Playgroud)
我将如何调用 Foo 并解码结果?(使用 Module.cwrap 或直接调用 Module._Foo )。我需要访问 Emscripten 堆栈才能做到这一点吗?这是在哪里记录的?
我有一个图像处理 Wasm 项目,它将不同的二值化算法应用于给定的图像。当我运行其中一种算法时,会产生此错误:
Uncaught abort("Cannot enlarge memory arrays to size 17100800 bytes (OOM). Either
(1) compile with -s TOTAL_MEMORY=X with X higher than the current value 16777216,
(2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or
(3) if you want malloc to return NULL (0)
instead of this abort, compile with -s ABORTING_MALLOC=0 ") at Error
Run Code Online (Sandbox Code Playgroud)
编译后"-s ALLOW_MEMORY_GROWTH=1",该算法在Chrome中并没有出错,而是将图像变成了黑色。连续第二次运行出现此错误:
Uncaught RuntimeError: memory access out of bounds
第一次在 Edge 中运行时,42.17134.1.0我收到此错误:
SCRIPT5147: The ArrayBuffer is …
如果您回答我关于 WebAssembly 多线程的问题,我将不胜感激。我想用 2 个线程(主线程和辅助线程)实现代码,这样就有一个全局变量用作辅助线程中的计数器变量,并在循环中递增它。和主线程,读取计数器变量,一次在运行指令之前,一次在运行指令之后(测量完成该指令所需的时间)。我已经实现了这个代码:
#include "pthread.h"
#include <stdio.h>
#include <unistd.h>
#include<chrono>
int i;
int counter;
void* timerfunction( void *ptr)
{
printf ("Thread Timer!\n");
//cout<<"Thread Timer!"<<endl;
while(1)
{
counter=counter+1;
}
pthread_exit("The thread was exited!");
}
int main()
{
pthread_t thread_id;
void *thread_result;
int c=0;
int l=pthread_create(&thread_id,NULL,timerfunction,&c);
int t1= counter;//reading the counter for the first one
//intended instruction that we want to measure its execution time
int t2= counter;//reading the counter for the second one
int t3 = t2 - t1;//computing …Run Code Online (Sandbox Code Playgroud) 我被困在如何使用 wasm 编译器在 React 代码中加载 C++ 函数。
我的 C++ 由两个文件组成,编译后生成一个 160kb 的 wasm 文件。这是我目前用于编译的命令(在 macOS 上运行)。
em++ ../main.cpp ../stringFormat.cpp -s WASM=1 -s EXPORT_ALL=1 -s MODULARIZE=1 -O3 --closure 1 -o lss.js -std=c++11
Run Code Online (Sandbox Code Playgroud)
然后我将 lss 和 wasm 文件一起复制到我的 React 代码中,在同一个文件夹中。
src
- utils
- wasm
lss.js
lss.wasm
Run Code Online (Sandbox Code Playgroud)
但是,每当我尝试在另一个文件中导入 lss.js 时,我的应用程序都会因一堆未定义的表达式而崩溃。
我的js文件
import * as lss from '../wasm/lss'
Run Code Online (Sandbox Code Playgroud)
./src/utils/wasm/lss.js
Line 10:6: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 11:69: Expected an assignment or function call and instead …Run Code Online (Sandbox Code Playgroud) emscripten ×10
javascript ×5
webassembly ×5
c ×3
c++ ×3
node.js ×2
asynchronous ×1
egl ×1
module ×1
opengl-es ×1
promise ×1
reactjs ×1
stdin ×1
wasm-bindgen ×1
web-worker ×1
webpack ×1