使用node.js中的emscripten编译的C库

时间:2020-12-14 16:02:32

After following instructions on the emscripten wiki I have managed to compile a small C library. This resulted in an a.out.js file.

按照emscripten wiki上的说明操作后,我设法编译了一个小型C库。这导致了一个a.out.js文件。

I was assuming that to use functions from this library (within node.js) something like this would have worked:

我假设使用这个库中的函数(在node.js中)这样的东西会起作用:

var lib = require("./a.out.js");
lib.myFunction('test');

However this fails. Can anyone help or point me to some basic tutorial related to this?

然而,这失败了。任何人都可以帮助或指出一些与此相关的基本教程吗?

2 个解决方案

#1


7  

The problem here is that your a.out.js file is going to look like this

这里的问题是你的a.out.js文件看起来像这样

function myFunction() {
  ...
}

Not like this

不是这样的

function myFunction() {
  ...
}

exports.myFunction = myFunction;

You need to write a build script that lists the tokens you want to publically export from each C program and appends exports.<token> = <token>;\n to the end of your file for each token.

您需要编写一个构建脚本,列出要从每个C程序公开导出的标记,并将导出。 = ; \ n附加到文件末尾的每个标记。

#2


7  

Actually, all the functions are already exported. Generated JavaScript contains following lines:

实际上,所有功能都已导出。生成的JavaScript包含以下行:

var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
// …

if (ENVIRONMENT_IS_NODE) {
  // …
  module['exports'] = Module;
}

If you got a function called my_fun in your C code, then you'll have Module._my_fun defined.

如果你的C代码中有一个名为my_fun的函数,那么你将定义Module._my_fun。

There are some problems with this approach, though.

但是,这种方法存在一些问题。

Optimizer may remove or rename some functions, so always specify them passing -s EXPORTED_FUNCTIONS="['_main','_fun_one','_fun_two']". Function signatures in C++ are bit mangled, so it's wise to extern "C" { … } the ones which you want to export.

优化器可能会删除或重命名某些函数,因此请始终指定它们传递-s EXPORTED_FUNCTIONS =“['_ main','_ fun_one','_ fun_two']”。 C ++中的函数签名有点被破坏,因此对于要导出的“C”{...}来说是明智的。

Furthermore, such a direct approach requires JS to C type conversions. You may want to hide it by adding yet another API layer in file added attached with --pre-js option:

此外,这种直接方法需要JS到C类型的转换。您可能希望通过添加附加了--pre-js选项的文件中的另一个API层来隐藏它:

var Module = {
  my_fun: function(some_arg) {
    javascript to c conversion goes here;
    Module._my_fun(converted_arg) // or with Module.ccall
  }
}

Module object will be later enhanced by all the Emscripten-generated goodies, so don't worry that it's defined here, not modified.

模块对象稍后将由所有Emscripten生成的好东西增强,所以不要担心它在此处定义,而不是修改。

Finally, you will surely want to consider Embind which is a mechanism for exposing nice JavaScript APIs provided by Emscripten. (Requires disabling newest fastcomp backend.)

最后,您一定要考虑使用Embind,这是一种公开Emscripten提供的优秀JavaScript API的机制。 (需要禁用最新的fastcomp后端。)

#1


7  

The problem here is that your a.out.js file is going to look like this

这里的问题是你的a.out.js文件看起来像这样

function myFunction() {
  ...
}

Not like this

不是这样的

function myFunction() {
  ...
}

exports.myFunction = myFunction;

You need to write a build script that lists the tokens you want to publically export from each C program and appends exports.<token> = <token>;\n to the end of your file for each token.

您需要编写一个构建脚本,列出要从每个C程序公开导出的标记,并将导出。 = ; \ n附加到文件末尾的每个标记。

#2


7  

Actually, all the functions are already exported. Generated JavaScript contains following lines:

实际上,所有功能都已导出。生成的JavaScript包含以下行:

var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
// …

if (ENVIRONMENT_IS_NODE) {
  // …
  module['exports'] = Module;
}

If you got a function called my_fun in your C code, then you'll have Module._my_fun defined.

如果你的C代码中有一个名为my_fun的函数,那么你将定义Module._my_fun。

There are some problems with this approach, though.

但是,这种方法存在一些问题。

Optimizer may remove or rename some functions, so always specify them passing -s EXPORTED_FUNCTIONS="['_main','_fun_one','_fun_two']". Function signatures in C++ are bit mangled, so it's wise to extern "C" { … } the ones which you want to export.

优化器可能会删除或重命名某些函数,因此请始终指定它们传递-s EXPORTED_FUNCTIONS =“['_ main','_ fun_one','_ fun_two']”。 C ++中的函数签名有点被破坏,因此对于要导出的“C”{...}来说是明智的。

Furthermore, such a direct approach requires JS to C type conversions. You may want to hide it by adding yet another API layer in file added attached with --pre-js option:

此外,这种直接方法需要JS到C类型的转换。您可能希望通过添加附加了--pre-js选项的文件中的另一个API层来隐藏它:

var Module = {
  my_fun: function(some_arg) {
    javascript to c conversion goes here;
    Module._my_fun(converted_arg) // or with Module.ccall
  }
}

Module object will be later enhanced by all the Emscripten-generated goodies, so don't worry that it's defined here, not modified.

模块对象稍后将由所有Emscripten生成的好东西增强,所以不要担心它在此处定义,而不是修改。

Finally, you will surely want to consider Embind which is a mechanism for exposing nice JavaScript APIs provided by Emscripten. (Requires disabling newest fastcomp backend.)

最后,您一定要考虑使用Embind,这是一种公开Emscripten提供的优秀JavaScript API的机制。 (需要禁用最新的fastcomp后端。)