我应该在 JS 中哪里定义 emscripten extern 函数?

Posted

技术标签:

【中文标题】我应该在 JS 中哪里定义 emscripten extern 函数?【英文标题】:Where should I defined emscripten extern functions in JS? 【发布时间】:2015-11-12 14:18:38 【问题描述】:

假设我在 C++ 中将函数 x 定义为:

extern "C" void x();

我在全局上下文中的 JS 中实现它

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

_x 在 asm 编译的 js 文件中定义,该文件被调用而不是我的实现。我做错了什么?

我在链接时收到此警告:

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)

【问题讨论】:

您能否阐明您的目标/用例是什么? emscripten编译JS到普通JS之间的通信(kripken.github.io/emscripten-site/docs/porting/…) 在 emscripten 编译的 JS 和普通 JS 之间传递一个字符串 (kripken.github.io/emscripten-site/docs/porting/…) 【参考方案1】:

如Implement a C API in javascript 中所述,您可以通过拥有一个调用mergeInto 的Javascript 文件来定义一个库,以将一个对象与您的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的警告框。

【讨论】:

【参考方案2】:

如果您想将字符串从 C++ 传递到 Javascript,则不必走Implement a C API in Javascript 的路线。相反,您可以使用EM_ASM* macros 直接内联Javascript。然后可以调用您定义的 Javascript 函数,并传递它们的值。

另外,要传递一个字符串,你需要确保传递一个 C 风格的字符串,然后在结果上使用 Emscripten 提供的 Pointer_stringify Javascript 函数:

#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;

【讨论】:

是否可以通过“在 Javascript 中实现 C API”来实现?因为这样更具可读性。

以上是关于我应该在 JS 中哪里定义 emscripten extern 函数?的主要内容,如果未能解决你的问题,请参考以下文章

Emscripten malloc 和跨 JS 和 C++ 的免费

如何告诉 Emscripten SDK 在哪里可以找到 Node?

使用 emscripten 将字符串从 C++ 传递给 JS

使用 emscripten 生成 python.cc.js

使用未声明的标识符 GluBuildMipMaps (emscripten)

EM_JS 无法在 emscripten 中导出函数