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", [] ]
});
你可以做很多更酷的事情。看看这里
如果这是一个节点库,只需将您的方法放在 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 包装预编译/安装的库。