Emscripten webworker - 自己的消息和依赖关系

时间:2016-03-11 10:24:36

标签: javascript c++ web-worker emscripten

我有一个C ++项目,我使用emscripten编译为Javascript。但是,由于资源限制和交互性原因,我希望在Webworker中运行它。

但是,我的项目使用stdin。我找到了一种方法来提供我自己的stdin实现,方法是用一个函数覆盖Module ['stdin'],该函数在总stdin时返回一个字符,并以0作为EOF关闭。 当脚本在页面内运行时,这是有效的,因为html文件中存在的Module对象与脚本共享。

当您作为webworker运行时,不会共享此模块对象。相反,消息传递确保Module的常规功能仍然有效。这不包括'stdin'。

我通过修改输出javascript来解决这个问题:

  • 答:添加包含此stdin规范的Module对象的实现。修改此函数以读取webworker的变量,就像它是stdin一样,并按每个字符提供它。
  • B:更改webworker的onmessage以调用处理我自己的事件的附加功能。
  • C:这个附加函数通过设置我指定的stdin函数读取的变量来监听事件并在事件是stdin的内容时做出反应。
  • D:在此附加事件上添加和删除运行依赖项,以防止在未指定stdin的情况下运行c ++代码。

在代码中:

Module['stdin_pointer'] = 0;
Module['stdin_content'] = "";

Module['stdin']=(function () {
   if (Module['stdin_pointer'] < Module['stdin_content'].length) {
      code = Module['stdin_content'].charCodeAt(Module['stdin_pointer']);
      Module['stdin_pointer']=Module['stdin_pointer']+1;
      return code;
   } else {
      return null;
   }
});

external = function(message){
   switch(message.data.target){
      case 'stdin' : {
          Module['idpCode'] = message.data.content;
          removeRunDependency('stdin');
          break;                        
      }
      default: throw 'wha? ' + message.data.target;
   }
};

[...]

addRunDependency("stdin");

[...]
//Change this in the original onmessage function:
//      default: throw 'wha? ' + message.data.target;
//to
default: {external(message);}
显然,这是一个&amp; c部分非常简单,因为它可以在js文件的开始(或接近开始)添加,但是b&amp; d(添加自己的依赖项并在循环中获取自己的messagehandler)需要您内联编辑代码。 由于我的项目非常大,找到编辑所需的行可能非常麻烦,只有在优化和模仿的emscripten代码中才会如此。 执行此操作的自动脚本以及变通方法本身可能会破坏新的emscripten版本。

是否有更好,更正确的方法来达到相同的行为?

谢谢!

//编辑: --separate-asm标志非常有用,因为我必须编辑的文件现在只有几行(以模仿形式)。它大大减轻了负担,但仍然不是一种正确的方式,所以我不愿意将其标记为已解决。

1 个答案:

答案 0 :(得分:1)

我知道实现您想要的唯一方法是不使用Emscripten提供的工作者API,并自行推送。所有细节都可能超出单个问题的范围,但在高水平,你需要......

作为旁注,我发现Emscripten提供的用于JavaScript功能的C ++包装器,例如工作者,图形,音频,http请求等,一开始就很好,但是有局限性而且没有揭露技术上可行的一切。我经常不得不自己动手来获得功能所需。虽然不是出于同样的原因,但我还必须为工作人员编写自己的API。