node-addon-api 的简单使用,c++数值、字符串、对象、数组转化为js可用数据。

环境

1,node-gyp:9.0.0
2,node:16.0.0
3,python:3.10.5
4,node-addon-api:5.0.0

如果你没有配置好node-gyp的环境,需要先配一下,可以看一下:node-gyp环境配置

打包配置

由于我所有列子都写在demo.cc里,所以我的打包文件没有改动,如果你的文件命名不一致,需要在binding.gyp的sources里改一下文件名。
如果你引入了多个C文件,需要将多个文件都在sources写一下。

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [	// 使用到的文件
        "addon.cc",
        "utils.cc",
        "cpp/xxx.cpp",	// 该文件在cpp文件夹里
        "cpp/SPP3/xxx.cpp"
      ],
      "include_dirs": [
        "<!@(node -p \"require('node-addon-api').include\")",
        "cpp\SPP3",	// 需要在这里将文件夹加一下
        "cpp"
      ],
      "dependencies": [
        "<!(node -p \"require('node-addon-api').gyp\")"
      ],
      "cflags!": ["-fno-exceptions"],
      "cflags_cc!": ["-fno-exceptions"],
      "defines": ["NAPI_CPP_EXCEPTIONS"],
      "xcode_settings": {
        "GCC_ENABLE_CPP_EXCEPTIONS": "YES"
      }
    }
  ]
}

1,数值

1,demo.cc

#include <napi.h>
#include<iostream>
#include<string>
using namespace Napi;
//直接返回c++的数值类型数据到js
Value getNumber(const CallbackInfo& info) {
  Env env = info.Env();
  int num = 2;
  std::cout << "c++-log=>" << num << std::endl;
  Number result = Number::New(env, num);

  return result;
}
// 接收js传来的两个数值,转化为C++可用的数值后,相加并将结果返回。没有做参数的类型检测,传入字符串或不传,会报错
Value addNumber(const CallbackInfo& info){
  Env env = info.Env();
  double arg0 = info[0].As<Number>().DoubleValue();
  double arg1 = info[1].As<Number>().DoubleValue();
  double num = arg0+arg1;
  Number result = Number::New(env, num);
  return result;
}

Object Init(Env env, Object exports) {
  exports.Set(String::New(env, "getNumber"), Function::New(env, getNumber));
  exports.Set(String::New(env, "addNumber"), Function::New(env, addNumber));
  return exports;
}

NODE_API_MODULE(addon, Init)

2,index.js

const addon = require('./build/Release/hello.node');


console.log("js--log=>",addon.getNumber());
console.log("js--log=>",addon.addNumber(3,2));

3,运行node index.js结果
在这里插入图片描述

2,字符串

1,demo.cc

#include <napi.h>
#include<iostream>
#include<string>
using namespace Napi;

Napi::Value getString(const CallbackInfo& info){
  Env env = info.Env();
  // 检测参数数量
  if(info.Length()<1){
    Napi::TypeError::New(env, "Wrong number of arguments")
        .ThrowAsJavaScriptException();
    return env.Null();
  }
  // 检测参数类型
  if(!info[0].IsString()){
    Napi::TypeError::New(env, "Wrong arguments")
        .ThrowAsJavaScriptException();
    return env.Null();
  }
  
  std::string str = info[0].As<Napi::String>();
  if(str == "hello"){
    str = "hello world!";
  }else{
    str = "Please say hello!";
  }
  Napi::String reslut = Napi::String::New(env,str);
  return reslut;
}

Napi::Object Init(Env env, Object exports){

  exports.Set(Napi::String::New(env,"getString"),Napi::Function::New(env,getString));
  return exports;
}

NODE_API_MODULE(addon,Init);

2,index.js

const addon = require('./build/Release/hello.node');
try {
  // 模拟没有参数的错误
  console.log("js--log=>",addon.getString());
} catch (error1) {
  console.log(error1);
  try {
    // 模拟参数类型的错误
    console.log("js--log=>",addon.getString(123));
  } catch (error2) {
    console.log(error2);
    // 正确输入
    console.log("js--log=>",addon.getString('ccc'));
    console.log("js--log=>",addon.getString('hello'));
  }
}

3,运行结果
在这里插入图片描述

3,对象

demo.cc

#include <napi.h>
#include<iostream>
#include<string>
using namespace Napi;

Napi::Value getObj( const CallbackInfo& info ){
  Env env = info.Env();
  // 为了精简示例代码,就不对数据类型进行检测了。

  // 接收并解析js传来的对象。
  Napi::Object obj = info[0].As<Napi::Object>();
  // Napi::Object obj = info[0].ToObject();
  std::string name = obj.Get(static_cast<napi_value>(Napi::String::New(info.Env(),"name"))).As<Napi::String>();
  std::cout << "c++_log=>" << name << std::endl;

  // 准备返回给js,c++对象
  Napi::Object result = Napi::Object::New(env);
  result.Set(Napi::String::New(env,"name"),Napi::String::New(env,name));
  result.Set(Napi::String::New(env,"age"),Napi::Number::New(env,36));
  result.Set(Napi::String::New(env,"height"),Napi::Number::New(env,175));
  result.Set(Napi::String::New(env,"weight"),Napi::Number::New(env,66.5));

  return result;
}

Napi::Object Init(Env env, Object exports){

  exports.Set(Napi::String::New(env,"getObj"),Napi::Function::New(env,getObj));
  return exports;
}

NODE_API_MODULE(addon,Init);

2,index.js

const addon = require('./build/Release/hello.node');

console.log("js--log=>",addon.getObj({name:"zhangsan"}));

3,运行结果
在这里插入图片描述

4,数组

1,demo.cc

#include <napi.h>
#include<iostream>
#include<string>
using namespace Napi;

Napi::Value getArr( const CallbackInfo& info ){
  Env env = info.Env();
  // 为了精简示例代码,就不对数据类型进行检测了。

  // 接收并解析js传来的数组。
  Napi::Array arr = info[0].As<Napi::Array>();
  int len = arr.Length();
  std::cout << "c++_log=>" << len << std::endl;
  std::string arr_1_string = arr.Get(static_cast<napi_value>(Napi::Number::New(info.Env(),0))).As<Napi::String>();
  std::cout << "c++_log=>" << arr_1_string << std::endl;
  int arr_2_Num = arr.Get(static_cast<napi_value>(Napi::Number::New(info.Env(),1))).As<Napi::Number>();
  std::cout << "c++_log=>" << arr_2_Num << std::endl;

  // 准备返回给js,c++数组
  Napi::Array result = Napi::Array::New(env);
  // 准备一个对象
  Napi::Object obj = Napi::Object::New(env);
  obj.Set(Napi::String::New(env,"name"),Napi::String::New(env,"zhangsan"));
  // 给数组填充值
  result.Set(Napi::Number::New(env,0),Napi::String::New(env,"balabala"));
  result.Set(Napi::Number::New(env,1),Napi::Number::New(env,36));
  result.Set(Napi::Number::New(env,2),Napi::Number::New(env,66.5));
  result.Set(Napi::Number::New(env,3),obj);

  return result;
}

Napi::Object Init(Env env, Object exports){

  exports.Set(Napi::String::New(env,"getArr"),Napi::Function::New(env,getArr));
  return exports;
}

NODE_API_MODULE(addon,Init);

2,index.js

const addon = require('./build/Release/hello.node');

console.log("js--log=>",addon.getArr(["laotie",666]));

3,运行结果
在这里插入图片描述

回调函数

1,demo.cc

#include <napi.h>
#include<iostream>
#include<string>
using namespace Napi;

void RunCallback(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::Function cb = info[0].As<Napi::Function>();
  cb.Call(env.Global(), {Napi::String::New(env, "hello world")});
}

Napi::Object Init(Env env, Object exports){

  exports.Set(Napi::String::New(env,"RunCallback"),Napi::Function::New(env,RunCallback));
  return exports;
}

NODE_API_MODULE(addon,Init);

2,index.js

const addon = require('./build/Release/hello.node');

function callBack(params) {
  console.log(params);
}

addon.RunCallback(callBack);

3,运行结果
在这里插入图片描述

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值