三木社区

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 269|回复: 0
打印 上一主题 下一主题

C++插件-包装 C++ 对象

[复制链接]

1562

主题

1564

帖子

4904

积分

博士

Rank: 8Rank: 8

积分
4904
跳转到指定楼层
楼主
发表于 2017-8-8 08:03:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下会创建一个 C++对象的包装MyObject,这样 他就能再 JavaScript 中用 new 实例化。首先在addon.cc中准备主要模块:
  1. // addon.cc
  2. #include <node.h>
  3. #include "myobject.h"

  4. using namespace v8;

  5. void InitAll(Handle<Object> exports) {
  6.   MyObject::Init(exports);
  7. }

  8. NODE_MODULE(addon, InitAll)
复制代码
接着在 myobject.h 创建包装,它继承自 node::ObjectWrap:
  1. // myobject.h
  2. #ifndef MYOBJECT_H
  3. #define MYOBJECT_H

  4. #include <node.h>
  5. #include <node_object_wrap.h>

  6. class MyObject : public node::ObjectWrap {
  7. public:
  8.   static void Init(v8::Handle<v8::Object> exports);

  9. private:
  10.   explicit MyObject(double value = 0);
  11.   ~MyObject();

  12.   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  13.   static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
  14.   static v8::Persistent<v8::Function> constructor;
  15.   double value_;
  16. };

  17. #endif
复制代码
在 myobject.cc 中实现各种暴露的方法,通过给构造函数添加 prototype 属性来暴露 plusOne 方法:
  1. // myobject.cc
  2. #include "myobject.h"

  3. using namespace v8;

  4. Persistent<Function> MyObject::constructor;

  5. MyObject::MyObject(double value) : value_(value) {
  6. }

  7. MyObject::~MyObject() {
  8. }

  9. void MyObject::Init(Handle<Object> exports) {
  10.   Isolate* isolate = Isolate::GetCurrent();

  11.   // Prepare constructor template
  12.   Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  13.   tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  14.   tpl->InstanceTemplate()->SetInternalFieldCount(1);

  15.   // Prototype
  16.   NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);

  17.   constructor.Reset(isolate, tpl->GetFunction());
  18.   exports->Set(String::NewFromUtf8(isolate, "MyObject"),
  19.                tpl->GetFunction());
  20. }

  21. void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  22.   Isolate* isolate = Isolate::GetCurrent();
  23.   HandleScope scope(isolate);

  24.   if (args.IsConstructCall()) {
  25.     // Invoked as constructor: `new MyObject(...)`
  26.     double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
  27.     MyObject* obj = new MyObject(value);
  28.     obj->Wrap(args.This());
  29.     args.GetReturnValue().Set(args.This());
  30.   } else {
  31.     // Invoked as plain function `MyObject(...)`, turn into construct call.
  32.     const int argc = 1;
  33.     Local<Value> argv[argc] = { args[0] };
  34.     Local<Function> cons = Local<Function>::New(isolate, constructor);
  35.     args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  36.   }
  37. }

  38. void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
  39.   Isolate* isolate = Isolate::GetCurrent();
  40.   HandleScope scope(isolate);

  41.   MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
  42.   obj->value_ += 1;

  43.   args.GetReturnValue().Set(Number::New(isolate, obj->value_));
  44. }
复制代码
测试:
  1. // test.js
  2. var addon = require('./build/Release/addon');

  3. var obj = new addon.MyObject(10);
  4. console.log( obj.plusOne() ); // 11
  5. console.log( obj.plusOne() ); // 12
  6. console.log( obj.plusOne() ); // 13
复制代码


回复

使用道具 举报

Archiver|手机版|小黑屋|三木电子社区 ( 辽ICP备11000133号-4 )

辽公网安备 21021702000620号

GMT+8, 2025-6-27 00:37 , Processed in 0.023802 second(s), 23 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表