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

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

  • 写一个node.js扩展
  • 使用node-ffi

  • node-ffi似乎是访问现有库的一个不错的选择,但是我是否在考虑是否要使用node-ffi?我必须编写一个C包装程序才能使C++可以访问吗? (这是我可以得到一个简单的测试用例以在Windows上使用Visual Studio的唯一方法)。

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

    最佳答案

    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++ lib编译为libmylibrary.dll/.so之后,这是将其包装在javascript中的方法:
    var ffi = require('ffi');
    
    var mylibrary = ffi.Library('libmylibrary', {
      "foo": [ "int", ["int"] ],
      "bar": [ "int", [] ]
    });
    

    您可以做很多更酷的事情。 checkout ,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包装预编译/安装的lib。

    关于c++ - node-ffi与 Node 扩展,用于访问现有的C++功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16783023/

    10-11 22:38
    查看更多