当前位置: 首页 > 编程笔记 >

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

彭礼骞
2023-03-14
本文向大家介绍node.js调用C++函数的方法示例,包括了node.js调用C++函数的方法示例的使用技巧和注意事项,需要的朋友参考一下

目前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文件中调用头文件


这里#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文件就可以正常使用了。

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

 类似资料:
  • 本文向大家介绍c++ 构造函数中调用虚函数的实现方法,包括了c++ 构造函数中调用虚函数的实现方法的使用技巧和注意事项,需要的朋友参考一下 我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数。这种调用都是对象已经构建完成的情况。那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: 输出: 0 1 2 也就是说,在构造函数中调用虚函数,调用的是正在构造的类中的虚函

  • BaaS.invokeFunction(functionName, params, sync) 参数说明 参数 类型 必填 描述 functionName Number 是 云函数名 params Object 否 传递给云函数的参数 sync Bool 否 是否等待返回函数执行结果,默认为 true 返回参数说明 参数 类型 描述 code Number code 为 0 时表示成功执行云函数,

  • 主要内容:阻塞代码实例,非阻塞代码实例Node.js 异步编程的直接体现就是回调。 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。 例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js

  • Node.js 异步编程的直接体现就是回调。 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。 例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js

  • 本文向大家介绍Node.js中用D3.js的方法示例,包括了Node.js中用D3.js的方法示例的使用技巧和注意事项,需要的朋友参考一下 前言 D3.js 是一个基于数据操作文档JavaScript库。D3帮助你给数据带来活力通过使用HTML、SVG和CSS。D3重视Web标准为你提供现代浏览器的全部功能,而不是给你一个专有的框架。结合强大的可视化组件和数据驱动方式Dom操作。下面主要介绍了No

  • 问题内容: 对不起任何较小的语法错误或其他错误,我正在使用Jitsi模块进行此操作,并且对Java不太熟悉,因此想确认正在发生的事情以及为什么以及如何对其进行修复。 使用按名称加载类方法创建类B的实例时,应用程序正在执行此操作: 在类B中调用重写的load() 初始化变量(根据调试器调用“私有字符串testString = null”),将其无效。 这是预期的Java行为吗?是什么原因造成的?它是