【问题标题】:node-ffi vs. node extension for accessing existing C++ functionality用于访问现有 C++ 功能的 node-ffi 与 node 扩展
【发布时间】:2013-05-28 02:34:21
【问题描述】:

我有一些现有的 C++ 代码可以在独立的 C++ 应用程序中进行数值处理。我现在想在新的 node.js 应用程序中使用该代码。

研究如何从node.js访问C++代码,有两个选择:

  1. 编写 node.js 扩展
  2. 使用node-ffi

node-ffi 似乎是访问现有 libraries 的好选择,但我是否正确地认为如果我使用 node-ffi 我必须编写一个 C 包装器以使我的 C++ 可访问? (这是我在 Windows 上使用 Visual Studio 获得简单测试用例的唯一方法)。

对于我的源代码已经是 C++ 而不是 C 的情况,在上述两个选项之间进行选择时有哪些注意事项?

【问题讨论】:

  • 你的代码中是否大量使用了继承、虚函数和模板
  • 没有模板。没有虚函数。一些继承,尽管如果需要我可以修改代码以避免这种情况。
  • 我认为编写包装器比编写包装器相对容易
  • 我同意,编写包装器并不难。我想知道我是否需要为node-ffi编写包装器,以及这是否比编写节点扩展更好。
  • 看起来您不必这样做,从我刚刚阅读的内容来看,您甚至可以使其与objective c一起使用

标签: c++ node.js node.js-addon node-ffi


【解决方案1】:

FFI 与动态 C 库一起使用。这意味着您必须在外部公开您的动态库。在 C++ 中,您可以使用 extern "C" 执行此操作,如下所示:

#ifdef __cplusplus
extern "C" {
#endif

int foo (int param){
  int ret = 0;
  // do C++ things
  return ret;
}

int bar(){
  int ret = 0;
  // do C++ things
  return ret;
}

#ifdef __cplusplus
}
#endif

这将使您的 C++ 函数可用于 C 事物,作为动态库方法。

在将 C++ 库编译为 libmylibrary.dll/.so 后,以下是在 javascript 中包装它的方法:

var ffi = require('ffi');

var mylibrary = ffi.Library('libmylibrary', {
  "foo": [ "int", ["int"] ],
  "bar": [ "int", [] ]
});

您可以做很多更酷的事情。看看吧,here

如果这是一个节点库,只需将您的方法放在 module.exports 中。以下是上述 C++ 代码包装的完整示例,带有同步和异步方法:

var ffi = require('ffi');

var mylibrary = ffi.Library('libmylibrary', {
  "foo": [ "int", ["int"] ],
  "bar": [ "int", [] ]
});

module.exports = {
  fooSync : mylibrary.foo,
  foo: mylibrary.foo.async,
  barSync : mylibrary.bar,
  bar: mylibrary.bar.async
};

我没有使用过node-ffi-generate,但是为你生成这些包装器看起来很酷。

如果我将此文件保存为 mylibrary.js,我可以这样使用它:

var mylib = require('./mylibrary.js');

var num = mylib.fooSync(1);

// or

mylib.foo(1, function(er, num){

});

至于“更好吗?”的问题。我想是的,对于大多数事情。如果你让你的方法外部 C,它们几乎可以在所有其他语言中工作,其中一些也有 FFI,所以你可以用任何你的目标语言编写上面的简单等价物。这意味着需要维护的代码很少,除了基本的“加载 C++ 库”和“弄乱它的签名以感觉适合语言 X”。它不是特定于节点的。另一个好处是常见的共享库(如 sqlite,在教程示例中给出。)您可能并不关心他们拥有的确切版本,或者想要用更多 C++ 代码包装它,需要编译才能使用它。使用 FFI,您可以仅使用 javascript 包装预编译/安装的库。

【讨论】:

  • 非常详细的答案,非常感谢!我写这个问题已经有一段时间了,我现在同意我认为使用 FFI 路由可能比编写扩展更直接。 node-ffi-generate 看起来很有趣。
  • 但您可能需要考虑性能。如果你经常打电话,那么 FFI 的幅度可能会更慢。这是一个详细的基准测试:bitbucket.org/juraf/node_ffi_vs_addon/src/master
猜你喜欢
  • 2013-09-09
  • 2019-02-03
  • 1970-01-01
  • 2012-02-06
  • 2018-12-26
  • 2021-01-13
  • 2017-05-12
  • 1970-01-01
相关资源
最近更新 更多