欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-22 11:23:04
目前nodejs调用c++主流的有两种方法,分别是addons和ffi addons是nodejs官方的c++扩展实现方案,但是由于需要使用模版,并且要对v8引擎有一定的...

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

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

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

要想node.js调用c++的函数等,须先将c++代码编译成二进制的.node文件。node.js官方文档中的c++ addons介绍了如何将c++的代码编译为二进制的.node文件。

一、步骤:

1.首先在项目目录进行npm install -g node-gyp下载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,下载地址:。我将addon.node文件添加到dependency walker发现缺少gdal/bin中的.dll。我将gdal/bin中的.dll文件复制到addon.node目录下,这时运行test.js文件就可以正常使用了。

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