node-ffi vs. node extension for accessing existing C++ functionality

眉间皱痕 提交于 2019-11-30 06:18:48

FFI works with dynamic C libraries. This means that you have to expose your dynamic library externally. In C++, you do this with extern "C", like this:

#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

This will make your C++ function available to C-things, as a dynamic library method.

Here is how you wrap this in javascript, after you have compiled your C++ lib as libmylibrary.dll/.so:

var ffi = require('ffi');

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

There are lots cooler things that you can do. Check it out, here

If this is a node library, just put your methods in module.exports. Here is a full example of a wrap of the above C++ code, with synchronous & asynchronous methods:

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

I haven't used node-ffi-generate, but it looks pretty cool for generating these sort of wrappers for you.

If I saved this file as mylibrary.js, I could use it like this:

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

var num = mylib.fooSync(1);

// or

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

});

As for the question of "is it better?" I think so, for most things. If you make your methods extern C, they will work in just about every other language, some of which also have FFI, so you would write the simple equivalent of the above in whatever your target language is. This means very little code to maintain, other than the basic "load C++ lib", and "mess around with it's signature to feel right for language X". It's not specific to node. Another bonus is for common shared libraries (like sqlite, given in tutorial example.) You maybe don't care exactly what version they have, or want to wrap it with more C++ code, that needs to be compiled to use it. Using FFI, you can wrap a pre-compiled/installed lib with just javascript.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!