Nodejs系列之使用V8编写C++插件

时间:2021-05-02

虽然现在大部分情况都是使用n-api来编写插件,但是底层毕竟是v8(和libuv),使用v8编写简单的插件,同时熟悉v8的使用。

本文介绍在写c++插件时,简单又常用的写法,其实本质上,写插件的难处在于底层的能力和对libuv、v8的了解。话不多说,直接看代码。

  • #include<node.h>
  • namespacedemo{
  • usingv8::FunctionCallbackInfo;
  • usingv8::Isolate;
  • usingv8::Local;
  • usingv8::Object;
  • usingv8::String;
  • usingv8::Value;
  • usingv8::FunctionTemplate;
  • usingv8::Function;
  • usingv8::Number;
  • usingv8::MaybeLocal;
  • usingv8::Context;
  • usingv8::Int32;
  • staticintseq;
  • //定义一个工具函数,生成seq
  • voidGenSeq(constFunctionCallbackInfo<Value>&args){
  • Isolate*isolate=args.GetIsolate();
  • args.GetReturnValue().Set(Number::New(isolate,++seq));
  • }
  • //定义一个加法函数
  • voidAdd(constFunctionCallbackInfo<Value>&args){
  • Isolate*isolate=args.GetIsolate();
  • inta=args[0].As<Int32>()->Value();
  • intb=args[1].As<Int32>()->Value();
  • args.GetReturnValue().Set(Number::New(isolate,a+b));
  • }
  • voidInitialize(
  • Local<Object>exports,
  • Local<Value>module,
  • Local<Context>context
  • ){
  • Isolate*isolate=context->GetIsolate();
  • //新建一个函数模版
  • Local<FunctionTemplate>func=FunctionTemplate::New(isolate);
  • //新建一个字符串表示函数名
  • Local<String>zaylee=String::NewFromUtf8(isolate,"zaylee",v8::NewStringType::kNormal).ToLocalChecked();
  • //设置函数名
  • func->SetClassName(zaylee);
  • //设置原型属性
  • func->PrototypeTemplate()->Set(isolate,"protoField",Number::New(isolate,1));
  • //设置对象属性
  • func->InstanceTemplate()->Set(isolate,"instanceField",Number::New(isolate,2));
  • func->InstanceTemplate()->Set(isolate,"add",FunctionTemplate::New(isolate,Add));
  • //设置函数对象本身的属性
  • func->Set(isolate,"funcField",Number::New(isolate,3));
  • //根据函数模版创建一个函数
  • Local<Function>ret=func->GetFunction(context).ToLocalChecked();
  • Local<String>Demo=String::NewFromUtf8(isolate,"Demo",v8::NewStringType::kNormal).ToLocalChecked();
  • //导出函数
  • exports->Set(context,Demo,ret).Check();
  • //导出工具函数
  • NODE_SET_METHOD(exports,"genSeq",GenSeq);
  • }
  • NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME,Initialize)
  • }//namespacedemo
  • 写个测试例子

  • const{Demo,genSeq}=require('./build/Release/test.node');
  • constdemo=newDemo();
  • console.log('demo对象:',demo,'\n');
  • console.log('原型属性:',demo.protoField,'\n');
  • console.log('执行add方法:',demo.add(1,2),'\n');
  • console.log('执行seq方法:',genSeq(),genSeq(),'\n');
  • 最后编写编译配置

  • {
  • "targets":[
  • {
  • "target_name":"test",
  • "sources":["./test.cc"]
  • }
  • ]
  • }
  • 看起来非常简单,大概的流程如下

  • npminstall-gnode-gyp
  • node-gypconfigure
  • node-gypbuild
  • nodetest.js
  • 拓展nodejs的方式很多,插件是一种,直接修改内核也是一种,之前有介绍过如何修改内核,有兴趣的同学也可以看一下。

    原文地址:https://mp.weixin.qq.com/s/oJDHYoPuCR7iy7XGp6eHTw

    声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

    相关文章