Для оптимальной производительности я хотел бы использовать emscripten в сочетании с инструментами закрытия, но плохо я не могу вызвать функцию, которую я определил в JavaScript из emscripten.
Обратите внимание, что я извлек минимальный пример из своего проекта, демонстрируя, что я имею в виду.
// 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!'));
Кстати, я использую оба вместе, и я включаю этот файл JavaScript перед файлом asmjs, просто чтобы убедиться, что 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(););
который должен работать как ожидалось.
Других решений пока нет …