Node Addon as bridge between javascript and C++

#include <node.h>

namespace HelloWorldDemo {
using v8::FunctionCallbackInfo; //used for passing arguments and returning val
using v8::Isolate; //v8 VM which has memory heap
using v8::Local; //Local is template of handle, Local<ClassType> means handle of ClassType
using v8::Object;
using v8::String;
using v8::Value;
using v8::Null;
using v8::Number;
using v8::Function;
using v8::Exception;
using v8::FunctionTemplate; //hello method
void hello (const FunctionCallbackInfo<Value>& args) { //get v8 VM
Isolate* isolate = args.GetIsolate(); //create js string "hello world" in v8 VM heap
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world."));
} //accumulate method
void accumulate (const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate(); /*throw exception*/
if (args.Length() < ) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate, "Arguments Number Error.")
));
return;
} /*throw exception*/
if (!args[args.Length() - ]->IsFunction()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate, "No Callback Error.")
));
return;
} //get callback function from js
Local<Function> callback = Local<Function>::Cast(args[args.Length() - ]); //accumulate
double sum = 0.0;
for (int i = ; i < args.Length() - ; ++i) {
/* throw exception if invalid number */
if (!args[i]->IsNumber()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate, "Arguments Type Error.")
));
return;
} else {
sum += args[i]->NumberValue();
}
} //call callback with accumulated result
Local<Number> num = Number::New(isolate, sum);
Local<Value> argv[] = { num };
callback->Call(Null(isolate), , argv);
} //return obj
void getPerson (const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate(); //create object
Local<Object> obj = Object::New(isolate);
//set (key,val) to object
obj->Set(
String::NewFromUtf8(isolate, "firstname"),
String::NewFromUtf8(isolate, "Java")
);
obj->Set(
String::NewFromUtf8(isolate, "lastname"),
String::NewFromUtf8(isolate, "Script")
);
//return object to js
args.GetReturnValue().Set(obj);
} //pass object to C++
void sayHiTo (const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
//get object from js
Local<Object> person = Local<Object>::Cast(args[]);
//get value from object
Local<String> fullname = String::Concat(
person->Get(String::NewFromUtf8(isolate, "firstname"))->ToString(),
person->Get(String::NewFromUtf8(isolate, "lastname"))->ToString()
);
//return value to js
args.GetReturnValue().Set(String::Concat(
String::NewFromUtf8(isolate, "Hi, "),fullname
));
} //return function
void getFunction (const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
//create js function
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, sayHiTo);
Local<Function> fn = tpl->GetFunction();
fn->SetName(String::NewFromUtf8(isolate, "sayHiTo"));
//return function to js
args.GetReturnValue().Set(fn);
} //initializtion function which is called when module is loaded into NodeJS for first time
void init (Local<Object> exports) {
/* exports method hello */
/* same as javascript's module.exports.hello = hello */
/* NODE_SET_METHOD can have many */ NODE_SET_METHOD(exports, "hello", hello);
NODE_SET_METHOD(exports, "accumulate", accumulate);
NODE_SET_METHOD(exports, "getPerson", getPerson);
NODE_SET_METHOD(exports, "getFunction", getFunction);
} //macro, set initializtion method of module
NODE_MODULE(NODE_GYP_MODULE_NAME, init)
}

//build addon
file: binding.gyp
{
   "targets": [

{
       "target_name": "myaddon",
       "sources": ["hello.cc"]
    },{
      "target_name": "accumulate",
      "sources": ["accumulate.cc"]
   }]
}

command:
node-gyp configure
node-gyp build

Using:

const myaddon = require('./build/Release/myaddon')

console.log('[HelloWorldDemo]' + myaddon.hello())

myaddon.accumulate(1, 3, 4, 7, (sum) => {
console.log('[FunctionArgumentsAndCallbacksDemo] 1 + 3 + 4 + 7 = ' + sum)
}) try {
myaddon.accumulate(1, 2, 'a', (sum) => {
console.log(sum)
})
} catch (err) {
console.log('[ExceptionDemo] ' + err)
} let someone = myaddon.getPerson()
console.log('[ReturnObjectDemo] ' + someone.firstname + someone.lastname) // return-function demo
let sayHiTo = myaddon.getFunction()
console.log('[ReturnFunctionDemo] ' + sayHiTo(someone))

Node Addon的更多相关文章

  1. ACK容器服务发布virtual node addon,快速部署虚拟节点提升集群弹性能力

    在上一篇博文中(https://yq.aliyun.com/articles/647119),我们展示了如何手动执行yaml文件给Kubernetes集群添加虚拟节点,然而,手动执行的方式用户体验并不 ...

  2. Node.js 自学之旅

    学习基础,JQuery 原生JS有一定基础,有自己一定技术认知(ps:原型链依然迷糊中.闭包6不起来!哎!) 当然最好有语言基础,C#,java,PHP等等.. 最初学习这个东西的原因很简单,在园子里 ...

  3. 使用neon 开发nodejs addon

    备注:开发使用的是mac 系统,需要安装rust nodejs .python2.7 Xcode 1. 安装neon npm install -g neon-cli   2. 创建简单项目 neon ...

  4. Node.js 自学之旅(初稿篇)

    学习基础,JQuery 原生JS有一定基础,有自己一定技术认知(ps:原型链依然迷糊中.闭包6不起来!哎!) 当然最好有语言基础,C#,java,PHP等等.. 最初学习这个东西的原因很简单,在园子里 ...

  5. nodejs 后台开发 和C++代码开发

    https://www.npmjs.com/package/node-gyp node-gyp Node.js native addon build tool Node.js native addon ...

  6. nodejs与c语言交互应用实例

    nodejs与c/c++交互目前主流的方式有两种,node addon c++ 和 node-ffi . 1.node addon c++ 1)nodejs从c语言读取数据 addon.c #incl ...

  7. Appium 教您完美win10安装Appium1.7.2支持win客户端自动化

    参考内容: https://testerhome.com/topics/10193https://testerhome.com/topics/8223https://testerhome.com/to ...

  8. ACK容器服务虚拟节点使用阿里云日志服务来收集业务容器日志

    按照这篇博文的介绍,可以在ACK集群上通过Helm的方式部署虚拟节点,提升集群的弹性能力.现在,通过虚拟节点部署的ECI弹性容器实例也支持将stdout输出.日志文件同步到阿里云日志服务(SLS)进行 ...

  9. babeljs源码

    babel.min.js!function(e,t){"object"==typeof exports&&"object"==typeof mo ...

随机推荐

  1. this指向详解及改变它的指向的方法

    一.this指向详解(彻底理解js中this的指向,不必硬背) 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是 ...

  2. 嵌入式应用开发第四阶段-基于rk3399的视频监控系统

    一.需求分析 伴随着嵌入式技术.图像处理技术和无线网络传输技术的发展,传统模拟视频监控系统和基于PC的远程视频监控系统由于自身的不足,已经无法满足现代社会应用中不断涌现出来的新需求,于是基于嵌入式技术 ...

  3. Python学习日记(二十八) hashlib模块、configparse模块、logging模块

    hashlib模块 主要提供字符加密算法功能,如md5.sha1.sha224.sha512.sha384等,这里的加密算法称为摘要算法.什么是摘要算法?它又称为哈希算法.散列算法,它通过一个函数把任 ...

  4. tar.bz2解压异常

    问题描述: [root@mvp-dd ~]# tar jxf ffmpeg-.tar.bz2 tar (child): bzip2: Cannot exec: No such file or dire ...

  5. 分布式数据库中间件、产品——sharding-jdbc、mycat、drds

    一般对于业务记录类随时间会不断增加的数据,当数据量增加到一定量(一般认为整型值为主的表达到千万级,字符串为主的表达到五百万)的时候,性能将遇到瓶颈,同时调整表结构也会变得非常困难.为了避免生产遇到这样 ...

  6. Docker03-安装Docker运行环境

    目录 Ubuntu 18 中安装Docker 查看Docker安装信息 查看Docker版本,命令:docker version 查看Docker运行信息,命令: docker info 检查安装是否 ...

  7. C# 验证控件组

    C# 验证控件允许使用ValidationGroup给验证控件分组,分组后的两组验证控件可以独立使用,互不相干.比如一个页面有登录和注册两个部分,假如使用验证控件组,提交的时候会对所有的验证控件进行验 ...

  8. 如果在使用谷歌的gson的时候,在返回时间类型的数据的时候,

    可能会出现在long类型的时间后面多3个0 如下图所示 可以自己创建一个json序列化的类 public class Date2LongSerializer extends JsonSerialize ...

  9. jmeter脚本中请求参数获取的几种方式

     a.从数据库获取: 譬如接口请求参数中id的值,我需要从数据库获取,如下设置: 先设置jdbc connection configuration,然后设置JDBC b.从CSV获取: 获取CSV文件 ...

  10. phantomJS+Python 隐形浏览器

    phantomjs解压后,把文件夹bin中的phantomjs.exe移到python文件夹中的Scripts中 实例: from selenium import webdriver driver = ...