node.js调用C++函数的方法示例


Posted in Javascript onSeptember 21, 2018

目前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官方文档中的例子

// addon.cc
#include <node.h>
namespace demo {
using v8::Exception;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;// This is the implementation of the "add" method// Input arguments are passed using the// const FunctionCallbackInfo<Value>& args struct
void Add(const FunctionCallbackInfo<Value>& args) {
 Isolate* isolate = args.GetIsolate();
 // Check the number of arguments passed.
 if (args.Length() < 2) {
 // Throw an Error that is passed back to JavaScript
 isolate->ThrowException(Exception::TypeError(
  String::NewFromUtf8(isolate, "Wrong number of arguments")));
 return;
 }
 // Check the argument types
 if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
 isolate->ThrowException(Exception::TypeError(
  String::NewFromUtf8(isolate, "Wrong arguments")));
 return;
 }
 // Perform the operation
 double value = args[0]->NumberValue() + args[1]->NumberValue();
 Local<Number> num = Number::New(isolate, value);
 // Set the return value (using the passed in
 // FunctionCallbackInfo<Value>&)
 args.GetReturnValue().Set(num);}
void Init(Local<Object> exports) {
 NODE_SET_METHOD(exports, "add", Add);}NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
} // namespace demo

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

{
 "targets": [
 {
  "target_name": "addon",
  "sources": [ "addon.cc" ]
 }
 ]
}

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

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

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

二、实例

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

node.js调用C++函数的方法示例

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

"include_dirs": [
  "./gdal/include"
  ],

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

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

这时的binding.gyp文件为

{
 "targets": [
 {
  "target_name": "addon",
  "sources": [
  "./C++_02/tile.cc"
  ],
  "include_dirs": [
  "./gdal/include"
  ],
  'libraries': [
   "../gdal/lib/gdal_i.lib",
  ],
 }
 ]
}

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

const addon=require(‘./build/Release/addon')
var imagefile = "/vsicurl/http://sasmac.oss-cn-beijing.aliyuncs.com/cog.tif";
var x = 160;
var y = 83;
var l = 9;
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文件就可以正常使用了。

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

Javascript 相关文章推荐
硬盘浏览程序,保存成网页格式便可使用
Dec 03 Javascript
使用prototype.js 的时候应该特别注意的几个问题.
Apr 12 Javascript
实现点击列表弹出列表索引的两种方式
Mar 08 Javascript
jQuery拖拽div实现思路
Feb 19 Javascript
JavaScript中的toDateString()方法使用详解
Jun 12 Javascript
深入解析JavaScript框架Backbone.js中的事件机制
Feb 14 Javascript
JQuery Mobile 弹出式登录框的实现方法
May 28 Javascript
深入理解React高阶组件
Sep 28 Javascript
vue-cli 3.x 配置Axios(proxyTable)跨域代理方法
Sep 19 Javascript
微信小程序自定义模态弹窗组件详解
Dec 24 Javascript
JS实现导航栏楼层特效
Jan 01 Javascript
Element Card 卡片的具体使用
Jul 26 Javascript
Vue中Quill富文本编辑器的使用教程
Sep 21 #Javascript
vue单页应用在页面刷新时保留状态数据的方法
Sep 21 #Javascript
vue如何安装使用Quill富文本编辑器
Sep 21 #Javascript
vue中设置、获取、删除cookie的方法
Sep 21 #Javascript
Vue实现动态添加或者删除对象和对象数组的操作方法
Sep 21 #Javascript
vue富文本编辑器组件vue-quill-edit使用教程
Sep 21 #Javascript
React实现全局组件的Toast轻提示效果
Sep 21 #Javascript
You might like
多重?l件?合查?(一)
2006/10/09 PHP
9条PHP编程小知识及易犯的小错误
2015/01/22 PHP
分享php分页的功能模块
2015/06/16 PHP
Centos PHP 扩展Xchche的安装教程
2016/07/09 PHP
php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击
2016/12/23 PHP
PHP中empty,isset,is_null用法和区别
2017/02/19 PHP
php实现将数据做成json的格式给前端使用
2018/08/21 PHP
又一个小巧的图片预加载类
2007/05/05 Javascript
jquery解析xml字符串简单示例
2014/04/11 Javascript
利用jQuery插件imgAreaSelect实现获得选择域的图像信息
2016/12/02 Javascript
详解tween.js 中文使用指南
2018/01/05 Javascript
深入理解JS的事件绑定、事件流模型
2018/05/13 Javascript
使用electron实现百度网盘悬浮窗口功能的示例代码
2018/10/24 Javascript
使用vue-cli3 创建vue项目并配置VS Code 自动代码格式化 vue语法高亮问题
2019/05/14 Javascript
vue实现多组关键词对应高亮显示功能
2019/07/25 Javascript
Vue解析带html标签的字符串为dom的实例
2019/11/13 Javascript
解决vue init webpack 下载依赖卡住不动的问题
2020/11/09 Javascript
npm全局环境变量配置详解
2020/12/15 Javascript
ubuntu系统下 python链接mysql数据库的方法
2017/01/09 Python
pandas带有重复索引操作方法
2018/06/08 Python
Django 拆分model和view的实现方法
2019/08/16 Python
python 并发编程 非阻塞IO模型原理解析
2019/08/20 Python
如何基于Python批量下载音乐
2019/11/11 Python
关于tf.TFRecordReader()函数的用法解析
2020/02/17 Python
python七种方法判断字符串是否包含子串
2020/08/18 Python
迪卡侬英国官网:Decathlon英国
2017/04/08 全球购物
Java的五个基础面试题
2016/02/26 面试题
搞笑婚礼主持词
2014/03/13 职场文书
公司承诺书怎么写
2014/05/24 职场文书
再婚婚前财产协议书范本
2014/10/19 职场文书
实习计划书范文
2015/01/16 职场文书
交通事故起诉书
2015/05/19 职场文书
python文件名批量重命名脚本实例代码
2021/04/22 Python
解决pytorch 损失函数中输入输出不匹配的问题
2021/06/05 Python
详解Golang如何优雅的终止一个服务
2022/03/21 Golang
一次SQL查询优化原理分析(900W+数据从17s到300ms)
2022/06/10 SQL Server