使用nan.h开发Node.js原生扩展时如何传递参数并返回值
基于nan.h的Node.js C++扩展传参与返回值实现
核心实现要点
- 入参获取:NAN定义的方法中,通过回调入参
info对象读取JS侧传入的参数,索引从0开始对应第一个参数,读取前必须做类型校验,避免非法入参导致程序崩溃。 - 类型转换:JS侧传入的字符串类型不能直接给C++
std::string使用,需要通过v8::String::Utf8Value做编码转换后再赋值。 - 返回值设置:所有需要返回给JS侧的值,必须转换为V8对应的类型(基础数值、字符串、数组等),再通过
info.GetReturnValue().Set()方法挂载到返回对象上,C++原生的基础类型、STL容器不能直接返回。 - 数组构造:需要返回数组结果时,用
Nan::New<v8::Array>()创建JS侧可识别的数组对象,逐位写入转换后的数值即可。
修改完成的完整C++代码
#include <iostream> #include <string> #include <bitset> #include <math.h> #include <nan.h> NAN_METHOD(encript) { // 入参校验:必须传入1个字符串类型参数 if (info.Length() < 1 || !info[0]->IsString()) { Nan::ThrowTypeError("Argument must be a string"); return; } // 读取JS传入的字符串参数,转换为C++ std::string v8::String::Utf8Value inputStr(Nan::To<v8::String>(info[0]).ToLocalChecked()); std::string data(*inputStr); // 原加密逻辑保留,替换硬编码输入为传入的参数 int* bit8Data = new int[data.size()]; for (std::size_t i = 0; i < data.size(); ++i) { bit8Data[i] = int(long(std::bitset<8>(data.c_str()[i]).to_ulong())); } // 动态计算输出数组长度,避免固定长度越界 size_t outputLen = ceil(data.size() * 8 / 6.0); int* bit6Data = new int[outputLen]; int remainder = 0, remainderLn = 0; int j = 0; for (std::size_t i = 0; i < data.size(); ++i) { if (remainderLn == 6) { bit6Data[j] = remainder; j++; remainder = 0; remainderLn = 0; } bit6Data[j] = int(remainder * pow(2, 8) + bit8Data[i]) / int(pow(2, remainderLn + 2)); remainder = int(remainder * pow(2, 8) + bit8Data[i]) % int(pow(2, remainderLn + 2)); remainderLn += 2; j++; } if (remainderLn > 0) bit6Data[j] = remainder * (pow(2, 6 - remainderLn)); // 构造JS侧可识别的数组,写入计算结果 v8::Local<v8::Array> resultArr = Nan::New<v8::Array>(outputLen); for (size_t i = 0; i < outputLen; ++i) { Nan::Set(resultArr, Nan::New<v8::Number>(i), Nan::New<v8::Number>(bit6Data[i])); } // 释放动态申请的数组内存 delete[] bit8Data; delete[] bit6Data; // 设置返回值 info.GetReturnValue().Set(resultArr); } NAN_MODULE_INIT(encriptInit) { Nan::SetMethod(target, "encript", encript); } NODE_MODULE(encript, encriptInit)
JS侧调用示例
// 加载编译好的原生模块 const cryptoModule = require('./build/Release/encript.node'); // 传入待加密字符串,获取返回的计算结果 const encryptResult = cryptoModule.encript("Hello World"); console.log(encryptResult);
内容的提问来源于stack exchange,提问作者Drek ForDer
相关产品推荐
相关产品推荐

