使用N-API从Node.JS调用C(+;+;)函数

使用N-API从Node.JS调用C(+;+;)函数,node.js,node-addon-api,n-api,Node.js,Node Addon Api,N Api,我想使用Node.js中的C函数,方法是将N-API与节点插件API模块包装器一起使用。这是我第一次使用N-API,我也是Node和C++的初学者。我有嵌入式系统C编程的经验,但是Node.jS/N-API这个东西我还不完全理解 我不想用Node.js中的这个原型调用C函数: unsigned char *MyFunction(unsigned char *data, size_t size, size_t min, size_t max) *data是指向包含RGB图像数据[R0、G0、B0

我想使用Node.js中的C函数,方法是将N-API与节点插件API模块包装器一起使用。这是我第一次使用N-API,我也是Node和C++的初学者。我有嵌入式系统C编程的经验,但是Node.jS/N-API这个东西我还不完全理解

我不想用Node.js中的这个原型调用C函数:

unsigned char *MyFunction(unsigned char *data, size_t size, size_t min, size_t max)
*data
是指向包含RGB图像数据[R0、G0、B0、R1、G1、B1,…]的数组的指针,其大小应在MyFunction中处理(提取RGB通道、反转等)

<>我目前的C++代码是:

#include <napi.h>

using namespace Napi;

Napi::Value Method(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();

  if (info.Length() != 3) {
    Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
    return env.Null();    
  }
  else {
    const Napi::Array inputArray = info[0].As<Napi::Array>();
    const float smin = info[1].As<Napi::Number>().FloatValue();
    const float smax = info[2].As<Napi::Number>().FloatValue();
    const unsigned int length = inputArray.Length();
    unsigned int i;
    Napi::Array outputArray = Napi::Array::New(env, length);
    Napi::Array redArray = Napi::Array::New(env, length / 3);
    Napi::Array greenArray = Napi::Array::New(env, length / 3);
    Napi::Array blueArray = Napi::Array::New(env, length / 3);

    // Extract Channels
    for (i = 0; i < (length / 3); i++) {
      redArray[i] = inputArray[i * 3];
      greenArray[i] = inputArray[i * 3 + 1];
      blueArray[i] = inputArray[i * 3 + 2];
    }

    // Apply Simple Color Balance to each channel
    for (i = 0; i < (length / 3); i++) {
      outputArray[i] = redArray[i];
    }
    return redArray;    // Test => this works
  }
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set(Napi::String::New(env, "Test"),
              Napi::Function::New(env, Method));
  return exports;
}

NODE_API_MODULE(module, Init)
#包括
使用名称空间Napi;
Napi::Value方法(const-Napi::CallbackInfo&info){
Napi::Env Env=info.Env();
如果(信息长度()!=3){
Napi::TypeError::New(env,“错误参数”).ThrowAsJavaScriptException();
返回env.Null();
}
否则{
常量Napi::数组inputArray=info[0].As();
常量float smin=info[1].As().FloatValue();
常量float smax=info[2].As().FloatValue();
常量unsigned int length=inputArray.length();
无符号整数i;
Napi::Array outputArray=Napi::Array::New(env,length);
Napi::Array redArray=Napi::Array::New(env,长度/3);
Napi::Array greenArray=Napi::Array::New(env,长度/3);
Napi::Array blueArray=Napi::Array::New(env,长度/3);
//提取通道
对于(i=0;i<(长度/3);i++){
redArray[i]=输入阵列[i*3];
greenArray[i]=输入阵列[i*3+1];
blueArray[i]=输入阵列[i*3+2];
}
//对每个通道应用简单的颜色平衡
对于(i=0;i<(长度/3);i++){
outputArray[i]=redArray[i];
}
return redArray;//Test=>这是有效的
}
}
Napi::对象初始化(Napi::Env Env,Napi::对象导出){
exports.Set(Napi::String::New(env,“Test”),
Napi::Function::New(env,Method));
出口退税;
}
节点API模块(模块,初始化)
这是节点部分:

const  sharp  = require('sharp');
sharp('testPic.jpg')
  .resize(800, 600)
  .toFile('SharpOut.jpg')
  .then( data => { 
    console.log('Resize & Negate => OK')
    // Extract Channel data
    sharp('SharpOut.jpg')
    .raw()
    .toBuffer()
    .then(data => {
      var smin = 0.0;
      var smax = 0.0;
      var testArr = [];
      for (let n = 0; n < data.length; n++) {
        testArr[n] = data[n];
      }      
      const HelloWorld = require('./build/Release/module.node');
      const result =  HelloWorld.Test(testArr, smin, smax);
    })
    .catch(err => {
      console.log('ERROR during extraction of RED channel. ERR:');
      console.log(err);
    });
  })
  .catch( err => { 
    console.log('ERROR');
    console.log(err);
  });
const sharp=require('sharp');
夏普('testPic.jpg')
.调整大小(800600)
.toFile('SharpOut.jpg')
.然后(数据=>{
log('Resize&Negate=>OK')
//提取通道数据
夏普('SharpOut.jpg'))
.raw()
.toBuffer()
。然后(数据=>{
var-smin=0.0;
var smax=0.0;
var testArr=[];
for(设n=0;n{
console.log('提取红色通道时出错。错误:');
控制台日志(err);
});
})
.catch(错误=>{
console.log('ERROR');
控制台日志(err);
});
我的问题
  • Sharp输出一个缓冲区,而不是一个数组,但使用
    ArrayBuffer
    而不是
    array
    我无法获得工作代码。编译是可以的,但是当我在节点中执行它时
  • 错误:D:\temp\testSCB\index.js:30:34处的参数无效

    这是这行代码
    constresult=HelloWorld.Test(testArr,smin,smax);)

  • 如果我更改
    redArray[I]=inputArray[I*3]
    to
    redArray[i]=~(inputArray[i*3])要反转颜色,我遇到两个错误:
  • 错误C2675:一元“~”:“Napi::Value”未定义此运算符或 转换为预定义运算符可接受的类型

    错误C2088:“~”:对于类来说是非法的

    我的问题 从node.js实现c函数的正确方法是什么


    谢谢你的帮助 如果您正在寻找一个纯N-API实现(不使用任何包装器),那么您可以看看下面的示例,它是在我学习纯N-API时创建的。 .

    此示例涵盖以下场景:

    • 从JavaScript接收ArrayBuffer
    • 在本机层创建ArrayBuffer并将其返回到JavaScript
    • 在本机层创建TypedArray并将其返回到JavaScript
    • 使用外部分配的内存在本机层创建一个ArrayBuffer 并将其返回到JavaScript
    它的JavaScript使用示例如下:


    如果您正在启动一个新的本机附加模块,我可能会鼓励您使用CMake.js而不是node-gyp(看起来node-gyp正在结束其支持)。您可以从我在N-API研究期间创建的示例项目中获得有关现代项目结构的更多信息

    谢谢!我已经使用了你的纯N-API示例,这对我帮助很大,现在我认为它应该很快就能工作了。。。也谢谢你的提示!