Reputation: 565
I need to create a Node.js native addon from some existing C code and I see that there are multiple ways to do that: using the new N-API (or the easier C++ native addon API) or using Node FFI. Also, I am not familiar with tools such as node-gyp
, and I have some questions to help understand how I can integrate the C code into my Node application:
node-gyp
? How should I do if I already have a library available but not compiled with node-gyp
(eg. .dylib
) and I want to use it in my Node application?Upvotes: 1
Views: 467
Reputation: 5308
1 - N-API is, in my perspective, the preferred method. It's faster than Node FFI and is part of the core node distribution. Node FFI's main advantage (from my quick read; I haven't used it) is that it allows making calls without writing c/c++ code. Whether you use N-API or the C++ native addon API is more a matter of preference on your part. The C++ API does remove some of the repetitive coding required by N-API. But if you're not using C++ to begin with that's probably not a good reason to change.
2 - you do not need to compile external libraries. Just put them in the binding.gyp
file's libraries section as follows:
{
'targets': [{
'target_name': 'addon-name',
'cflags!': [ '-fno-exceptions' ],
'cflags_cc!': [ '-fno-exceptions' ],
'xcode_settings': { 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'CLANG_CXX_LIBRARY': 'libc++',
'MACOSX_DEPLOYMENT_TARGET': '10.7',
},
'msvs_settings': {
'VCCLCompilerTool': { 'ExceptionHandling': 1 },
},
'include_dirs': [
'<!@(node -p "require(\'node-addon-api\').include")',
],
'sources': [
'src/addon-name.cc'
],
'conditions': [
['OS in "linux"', {
'include_dirs': [
'<!@(node -p "require(\'node-addon-api\').include")',
'<(module_root_dir)/'
],
'libraries': [
'-ldylib',
'-L<(module_root_dir)/dylib/',
'-Wl,-rpath-link,<(module_root_dir)/dylib/',
'-Wl,-rpath,\$$ORIGIN/../../dylib/'
],
}]
]
}]
}
Most of the boilerplate for bindings.gyp
was generated by the conversion tool which is part of the node-addon-api package. I included my own libraries section because I distribute a library with my package and figuring out how to embed $ORIGIN
as the location of the file was hard-won. So if you plan on distributing the library this provides a headstart on loading it when not installed in a system directory.
Upvotes: 3