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. 【面试突击】- 2019年125条常见的java面试笔试题汇总(一)

    1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部 问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过程抽象,二 ...

  2. Vue编程式跳转

    编程式跳转 <template> <ul class = "prolist"> <!-- //产品 --> <!-- :to = &quo ...

  3. Java服务端口被占用问题

    在改code的时候eclipse突然崩溃了,未响应状态等了好久也没转完,只能结束进程了,再次打开eclipse果然无法启动项目.报的错误是端口被占用. 又不想重启电脑,只能记录下微服务下的卡死清理端口 ...

  4. 使用PATH变量进行Linux权限升级技巧

    0x00 前言 在解决了几个OSCP挑战之后,我们决定写一篇关于用于Linux权限升级的各种方法的文章,这对我们的读者在其渗透测试项目中有所帮助.在本文中,我们将学习“使用$path变量的各种方法”以 ...

  5. 判断RecyclerView到达底部的几种方法

    参考文章:https://www.jianshu.com/p/c138055af5d2 1.比较lastItem的pos 通过比较当前屏幕可见最后一个item的position和整个RV的最后一个it ...

  6. ECharts大屏可视化【词云,堆积柱状图,折线图,南丁格尔玫瑰图】

    一.简介 参考ECharts快速入门:https://www.cnblogs.com/yszd/p/11166048.html 二.代码实现 <!DOCTYPE html> <htm ...

  7. python之路第一天

    2018-07-11星期三 创建自己的博客(博客园): 登陆 我的博客 随笔:所有人在博客中都能看见的文章 文章:别人看不见,只能URL访问--我把网页地址发给你,你才能看到 日志:别人看不到,URL ...

  8. MySQL Replication--复制延迟03--Seconds_Behind_Master计算

    Seconds_Behind_Master计算原理 当从库上复制IO进程和复制SQL进程正常运行,且SQL线程处于执行状态而非等待IO进程同步BINLOG时,复制延迟时间计算如下: 复制延迟时间(Se ...

  9. Python的路径操作(os模块与pathlib模块)

    Python的路径操作(os模块与pathlib模块) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.os.path模块(Python 3.4版本之前推荐使用该模块) #!/u ...

  10. docker学习6-docker-compose容器集群编排

    前言 实际工作中我们部署一个应用,一般不仅仅只有一个容器,可能会涉及到多个,比如用到数据库,中间件MQ,web前端和后端服务,等多个容器. 我们如果一个个去启动应用,当项目非常多时,就很难记住了,所有 ...