经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JSJS库框架 » JavaScript » 查看文章
node.js调用C++函数的方法示例
来源:jb51  时间:2018/9/25 19:02:23  对本文有异议

目前nodejs调用c++主流的有两种方法,分别是addons和ffi

addons是nodejs官方的c++扩展实现方案,但是由于需要使用模版,并且要对v8引擎有一定的了解,入门门槛较高。

ffi是nodejs直接调用so库的一种实现,可以调用纯c的接口。

要想node.js调用C++的函数等,须先将C++代码编译成二进制的.node文件。node.js官方文档https://nodejs.org/dist/latest-v8.x/docs/api/addons.html中的C++ addons介绍了如何将C++的代码编译为二进制的.node文件。

一、步骤:

1.首先在项目目录进行npm install -g node-gyp下载node-gyp模块,配置环境参考https://github.com/nodejs/node-gyp

2.这是node官方文档中的例子

  1. // addon.cc
  2. #include <node.h>
  3. namespace demo {
  4. using v8::Exception;
  5. using v8::FunctionCallbackInfo;
  6. using v8::Isolate;
  7. using v8::Local;
  8. using v8::Number;
  9. using v8::Object;
  10. using v8::String;
  11. using v8::Value;// This is the implementation of the "add" method// Input arguments are passed using the// const FunctionCallbackInfo<Value>& args struct
  12. void Add(const FunctionCallbackInfo<Value>& args) {
  13. Isolate* isolate = args.GetIsolate();
  14. // Check the number of arguments passed.
  15. if (args.Length() < 2) {
  16. // Throw an Error that is passed back to JavaScript
  17. isolate->ThrowException(Exception::TypeError(
  18. String::NewFromUtf8(isolate, "Wrong number of arguments")));
  19. return;
  20. }
  21. // Check the argument types
  22. if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
  23. isolate->ThrowException(Exception::TypeError(
  24. String::NewFromUtf8(isolate, "Wrong arguments")));
  25. return;
  26. }
  27. // Perform the operation
  28. double value = args[0]->NumberValue() + args[1]->NumberValue();
  29. Local<Number> num = Number::New(isolate, value);
  30. // Set the return value (using the passed in
  31. // FunctionCallbackInfo<Value>&)
  32. args.GetReturnValue().Set(num);}
  33. void Init(Local<Object> exports) {
  34. NODE_SET_METHOD(exports, "add", Add);}NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
  35. } // namespace demo

3.然后在项目目录下使用类似JSON的格式创建在项目顶层调用的文件binding.gyp文件,内容为

  1. {
  2. "targets": [
  3. {
  4. "target_name": "addon",
  5. "sources": [ "addon.cc" ]
  6. }
  7. ]
  8. }

4.在终端输入node-gyp configure命令生成一个build文件夹,然后输入node-gyp build命令生成编译addon.node文件

5.在node文件比如test.js文件中const addon=require(‘./build/Release/addon')调用生成的模块

  1. // test.js
  2. const addon = require('./build/Release/addon');
  3. console.log('This should be eight:', addon.add(3, 5));//结果为8

二、实例

最近公司让我研究node调用C++,C++的代码是调用了GDAL库开发的功能。要在tile.cc文件中调用头文件


这里#include调用的gdal_priv.h和ogrsf_frmts.h头文件在gdal/include文件夹中,所以要在binding.gyp文件中source后面添加

  1. "include_dirs": [
  2. "./gdal/include"
  3. ],

然后如果现在就运行node-gyp configure build命令会报“无法解析的外部符号”的错误,这是因为还需要加入调用的链接库,需要在binding.gyp文件中加入

  1. 'libraries': [
  2. "../gdal/lib/gdal_i.lib",
  3. ],

这时的binding.gyp文件为

  1. {
  2. "targets": [
  3. {
  4. "target_name": "addon",
  5. "sources": [
  6. "./C++_02/tile.cc"
  7. ],
  8. "include_dirs": [
  9. "./gdal/include"
  10. ],
  11. 'libraries': [
  12. "../gdal/lib/gdal_i.lib",
  13. ],
  14. }
  15. ]
  16. }

这时再进行node-gyp configure build命令就不会报错生成addon.node文件,但是当我运行test.js文件

  1. const addon=require(‘./build/Release/addon')
  2. var imagefile = "/vsicurl/http://sasmac.oss-cn-beijing.aliyuncs.com/cog.tif";
  3. var x = 160;
  4. var y = 83;
  5. var l = 9;
  6. console.log(addon.tileload(imagefile, x, y, l));

会报错'找不到指定的模块',但是我们在build/Release文件中能找到addon.node文件,这是因为缺少依赖也就是缺少.dll。下载 Dependency Walker,这个软件可以帮你确定一下缺少什么.dll,下载地址:http://www.dependencywalker.com/。我将addon.node文件添加到Dependency Walker发现缺少gdal/bin中的.dll。我将gdal/bin中的.dll文件复制到addon.node目录下,这时运行test.js文件就可以正常使用了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号