Node Addon
2024-08-28 01:45:12
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))
最新文章
- python Django 进阶篇
- contiki-process结构体
- shell 题
- JSP 自定义标签
- Trie树-可持久化
- OpenStack 镜像制作
- 在MAC上安装虚拟机搭建Ubuntu开发环境
- light工具
- 转:CentOS6.3配置yum源
- Linux_Shell type
- C#控制台程序本地化应用(Localization)
- Linux 系统应用编程——进程基础
- 转载 Java设计模式
- DRF缓存
- Typora 使用说明
- [ Java面试题 ]并发篇
- PHP 【五】
- JAVA工具类-StrUtils
- 采用shell脚本定时清理Tomcat日志
- 【python】self &; cls
热门文章
- jetbrains全家桶激活
- PM2 对 Node 项目进行线上部署与配置
- 【OGG】OGG简单配置双向复制(三)
- myEclipse项目部署点击Finish按钮没反应
- 基于centos7.6离线部署开k3s
- Linux环境变量设置declare/typeset
- 如何在Win7电脑上增加新磁盘分区?
- 【Mybatis异常】Caused by: java.sql.SQLException: Parameter index out of range (1 >; number of parameters, which is 0).
- Python_类的继承与方法重写
- 【Django2.0】python manage.py makemigrations 和 python manage.py migrate的区别