标签: emscripten

使用Emscripten Worker API传输数据而不进行复制

有没有办法让Emscripten在Web工作者和主UI线程之间传输而不是复制数据?

Emscripten有一个管理Web Workers之间通信API,我认为它只是使用了引擎盖下的postMessage/ onmessagemechanism.查看Emscripten Worker API的源代码,它似乎在调用时使用该transferList选项postMessage,因此数据将被复制.

实际上,我认为它至少被复制了两次:首先是线程之间的浏览器,然后是Emscripten第二次将它复制到Emscripten管理的堆空间中.如果您希望数据在回调后继续在接收端生存,则必须第三次复制,因为根据文档,传递给回调的数据仅保证在回调期间存在.

从顶部重复我的问题:有没有办法让Emscripten通过在Web worker和主UI线程之间传输而不是复制数据来避免所有这些复制?

javascript c c++ web-worker emscripten

8
推荐指数
1
解决办法
537
查看次数

如何从node.js使用WebAssembly?

我目前正在开发一个个人的Node.js(> = 8.0.0)项目,它要求我调用C子程序(以改善执行时间).我正在尝试使用WebAssembly来执行此操作,因为我需要在浏览器中打开时最终代码兼容.

我使用Emscripten将C代码编译成WebAssembly,并且在此之后不知道如何继续.

任何正确方向的帮助都会很棒.谢谢!

node.js emscripten webassembly

8
推荐指数
1
解决办法
4600
查看次数

可交换的JS代码以及从C ++生成的模块是否可以在浏览器中使用?

从今天开始,有任何方法可以将本机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时对此问题的修改,但现在我降低了期望。

javascript c++ module emscripten webpack

8
推荐指数
0
解决办法
120
查看次数

编译着色器后程序停止绘制

我正在研究要编译为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)

opengl-es opengl-es-2.0 egl emscripten

8
推荐指数
1
解决办法
145
查看次数

如何将 emscripten 浏览器输入法从 window.prompt 更改为更合理的方法?

我有一个 C++ 函数,它曾经被调用消耗来自 stdin 的输入。使用 emscripten 将此函数导出到 javascript 会导致调用 window.prompt。

与浏览器提示交互确实是一项乏味的任务。首先,您一次只能粘贴一行。其次,指示 EOF 的唯一方法是按“取消”。最后但并非最不重要的唯一方法(在我的函数的情况下)使其停止通过 window.prompt 要求用户输入是通过选中防止弹出更多提示的复选框。

对我来说,最好的输入方法是阅读一些 blob。我知道我可以破解 library.js 但我看到了一些问题:

  1. 读取 blob 是异步的。
  2. 要读取 blob,首先必须打开用户必须先选择的文件。
  3. 我真的不知道如何阻止我的函数永远读取这个 blob - 没有像 window.prompt 这样的复选框,我不确定如果不是在 window.prompt 情况下发现 EOF 是否会阻止它(仅检查复选框有帮助)。

最好的解决方案是某种回调,但我希望看到更有经验的用户的提示。

javascript c++ stdin node.js emscripten

7
推荐指数
1
解决办法
2154
查看次数

来自 C 代码的异步 JavaScript 库调用完成得太晚了

我正在使用 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)

javascript c asynchronous promise emscripten

7
推荐指数
1
解决办法
880
查看次数

你如何调用一个 C 函数,它通过 Emscripen/Wasm 从 JS 按值获取(或返回)一个结构?

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 堆栈才能做到这一点吗?这是在哪里记录的?

javascript c emscripten webassembly

7
推荐指数
2
解决办法
3336
查看次数

为什么在 WebAssembly 中 ALLOW_MEMORY_GROWTH=1 失败而 TOTAL_MEMORY=512MB 成功?

我有一个图像处理 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 …

emscripten webassembly

7
推荐指数
1
解决办法
7124
查看次数

WebAssembly 中的多线程

如果您回答我关于 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)

multithreading emscripten webassembly wasm-bindgen

7
推荐指数
1
解决办法
8157
查看次数

在 React 中为大文件(超过 4kb)加载 WASM 模块的正确方法

我被困在如何使用 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 reactjs webassembly

7
推荐指数
1
解决办法
1395
查看次数