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))

最新文章

  1. python Django 进阶篇
  2. contiki-process结构体
  3. shell 题
  4. JSP 自定义标签
  5. Trie树-可持久化
  6. OpenStack 镜像制作
  7. 在MAC上安装虚拟机搭建Ubuntu开发环境
  8. light工具
  9. 转:CentOS6.3配置yum源
  10. Linux_Shell type
  11. C#控制台程序本地化应用(Localization)
  12. Linux 系统应用编程——进程基础
  13. 转载 Java设计模式
  14. DRF缓存
  15. Typora 使用说明
  16. [ Java面试题 ]并发篇
  17. PHP 【五】
  18. JAVA工具类-StrUtils
  19. 采用shell脚本定时清理Tomcat日志
  20. 【python】self &amp; cls

热门文章

  1. jetbrains全家桶激活
  2. PM2 对 Node 项目进行线上部署与配置
  3. 【OGG】OGG简单配置双向复制(三)
  4. myEclipse项目部署点击Finish按钮没反应
  5. 基于centos7.6离线部署开k3s
  6. Linux环境变量设置declare/typeset
  7. 如何在Win7电脑上增加新磁盘分区?
  8. 【Mybatis异常】Caused by: java.sql.SQLException: Parameter index out of range (1 &gt; number of parameters, which is 0).
  9. Python_类的继承与方法重写
  10. 【Django2.0】python manage.py makemigrations 和 python manage.py migrate的区别