【问题标题】:How to use emscripten in conjunction with the closure tools如何结合闭包工具使用 emscripten
【发布时间】:2023-03-03 16:25:01
【问题描述】:

为了获得最佳性能,我想将 emscripten 与闭包工具结合使用,但我无法从 emscripten 调用我在 JavaScript 中定义的函数。

请注意,我从我的项目中提取了一个最小示例来说明我的意思。

// test.cc
#include <iostream>

#include "emscripten.h"

int main() {
  std::cout << "Hello, World!\n";
  EM_ASM(goog.dom.appendChild(
      document.body,
      goog.dom.createDom('p', {'font-weight' : 700}, 'Hello, World!'));
  );
}

所以“你好,世界!”打印正确,但随后:

exception thrown: ReferenceError: goog is not defined,ReferenceError: goog is not defined

即使 goog 应该在我编译并包含闭包库后就已经定义了,即使进行了高级优化,以便获得最佳性能。

现在,如果我在 JavaScript 中做同样的事情,它完全可以正常工作:

goog.provide('main');
goog.require('goog.dom');

console.log('Hello, World!');
goog.dom.appendChild(document.body, 
  goog.dom.createDom('p', {'font-weight': 700}, 'Hello, World!'));

顺便说一下,我同时使用了这两个文件,我在 asmjs 文件之前包含了这个 JavaScript 文件,只是为了确保确实定义了 goog

另一个值得注意的有趣的事情是,当我使用简单的优化进行编译时,它实际上可以工作。

那么如何将 emscripten 与闭包库和闭包编译器结合使用呢?

【问题讨论】:

    标签: c++ google-closure-compiler emscripten google-closure-library


    【解决方案1】:

    这是因为具有高级优化的闭包编译器会优化掉所有不需要的东西。

    因此,您需要导出您要调用的符号。

    我实际上会在 JavaScript 中完成整个事情,然后导出一个符号,这样您就不必导出整个 goog.dom 命名空间:

    goog.provide('asmjs');
    goog.require('goog.dom');
    /** @export */
    asmjs.helloWorld = function() {
      goog.dom.appendChild(document.body, 
        goog.dom.createDom('p', {'font-weight': 700}, 'Hello, world!'));
    };
    goog.exportSymbol('asmjs.helloWorld', asmjs.helloWorld);
    

    所以你可以调用:

    EM_ASM(asmjs.helloWorld(););
    

    应该可以按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2019-01-02
      相关资源
      最近更新 更多