Где я должен определить внешние функции emscripten в JS?

Предположим, у меня есть функция x в C++, определенная как:

extern "C" void x();

и я реализую это в JS в глобальном контексте

function _x() { console.log('x called'); }

_x определяется в js-файле, скомпилированном asm, который вызывается, а не в моей реализации. Что я делаю неправильно?

Я получаю это предупреждение при связывании:

warning: unresolved symbol: x

Вот трассировка стека:

Uncaught abort() at Error
at jsStackTrace (http://localhost/module.js:978:13)
at stackTrace (http://localhost/module.js:995:22)
at abort (http://localhost/module.js:71106:25)
at _x (http://localhost/module.js:5829:46)
at Array._x__wrapper (http://localhost/module.js:68595:41)
at Object.dynCall_vi (http://localhost/module.js:68442:36)
at invoke_vi (http://localhost/module.js:7017:25)
at _LoadFile (http://localhost/module.js:7573:6)
at asm._LoadFile (http://localhost/module.js:69219:25)
at eval (eval at cwrap (http://localhost/module.js:554:17), <anonymous>:6:26)

person Chakradar Raju    schedule 12.11.2015    source источник
comment
Можете ли вы уточнить, какова ваша цель / вариант использования?   -  person Michal Charemza    schedule 12.11.2015
comment
Связь между JS, скомпилированным emscripten, и обычным JS (kripken.github.io/emscripten-site/docs/porting/)   -  person Chakradar Raju    schedule 12.11.2015
comment
Передача строки между скомпилированным emscripten JS в обычный JS (kripken.github.io/emscripten-site/docs/porting/)   -  person Chakradar Raju    schedule 12.11.2015


Ответы (2)


Как описано в Реализуя C API в Javascript, вы определяете библиотеку, имея файл Javascript, который вызывает mergeInto для объединения объекта с вашими функциями Javascript в LibraryManager.library. Затем вы компилируете с параметром --js-library для передачи местоположения вашей библиотеки.

Например, у вас может быть файл Javascript с вашей библиотекой одной функции.

// In library.js
mergeInto(LibraryManager.library, {
  x: function() {
    alert('hi');
  },
});

основной файл C++, который вызывает эту функцию

// in librarytest.cc
extern "C" void x();

int main()
{
  x();
  return 0;
}

и скомпилировать в HTML и Javascript с помощью

em++ librarytest.cc --js-library library.js -o librarytest.html

затем вы загружаете librarytest.html в браузере, он покажет окно предупреждения с hi.

person Michal Charemza    schedule 21.11.2015

Если вы хотите передать строку из C++ в Javascript, вам не нужно идти по пути Реализовать C API в Javascript. Вместо этого вы можете использовать Макросы EM_ASM* для прямого встраивания Javascript. Затем он может вызывать функции Javascript, которые вы определили, и передавать их значения.

Кроме того, чтобы передать строку, вам нужно убедиться, что вы передаете строку в стиле C, а затем использовать предоставленную Emscripten функцию Javascript Pointer_stringify для результата:

#include <string>

#include <emscripten.h>

int main()
{
  std::string myString("This is a string in C++");

  EM_ASM_ARGS({
    console.log(Pointer_stringify($0));
  }, myString.c_str());

  return 0;
}
person Michal Charemza    schedule 15.11.2015
comment
Можно ли это сделать с помощью реализации C API в Javascript? потому что это более читабельно. - person Chakradar Raju; 16.11.2015