如何将emscripten与闭包工具结合使用

How to use emscripten in conjunction with the closure tools

本文关键字:工具 结合 闭包 emscripten      更新时间:2023-10-16

为了获得最佳性能,我想将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

即使CCD_ 1在我编译并包含闭包库之后就应该定义了,即使使用了高级优化,这样我也可以获得最大的性能。

现在,如果我在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与闭包库和闭包编译器结合使用呢?

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

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

实际上,我会在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(););

这应该如预期的那样工作。