0

I'm creating a node.js addon, which has bunch of classes. I want to organize them in a hierarchical namespace. If I were doing this in Javascript it would look like this

var com = function() {};

com.example = function() {};

com.example.Person = function () {};

var p = new com.example.Person();

I'm using Nan to write my node.js binding. To achieve the above result I've written code as follows:

com.h

namespace addon {
  void init(Local<Object> exports);
}

com.cpp

void addon::init(Local<Object> exports)
{
  addon::Example::Init(exports);
}

NODE_MODULE(com, com::init)

example.h

namespace addon {
  class Example : public Nan::ObjectWrap {
    static void Init(v8::Local<v8::Object> exports);
  }
}

example.cpp

void addon::Example::Init(v8::Local<v8::Object> exports) {

  // Prepare constructor template
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("example").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  addon::Person::Init(tpl);

  constructor.Reset(tpl->GetFunction());
}

person.h

namespace addon {
  class Person : public Nan::ObjectWrap {
    static void Init(v8::Local<v8::FunctionTemplate> exports);
  }
}

person.cpp

void addon::Person::Init(v8::Local<v8::FunctionTemplate> nmspace) {
  Nan::HandleScope scope;

  // Prepare constructor template
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("Person").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  // ...

  constructor.Reset(tpl->GetFunction());
  nmspace->Set(Nan::New("Person").ToLocalChecked(), tpl->GetFunction()); // XXXXXX

}

This code compiles and also successfully passes the tests when run. However I get a warning when the addon is loaded.

(node) v8::FunctionTemplate::Set() with non-primitive values is deprecated
(node) and will stop working in the next major release.

It prints a stack trace. The top of this trace is at the line marked XXXXXX.

If this is not the recommended way to define a FunctionTemplate as a member of another FunctionTemplate, then what's the right way to achieve it? Any ideas?

4

1 回答 1

0

我找到了一个简单的方法来做到这一点。我突然想到,我可以使用以下 Javascript 代码实现相同的目标。

var com = {};
com.example = {};
com.example.Person = function () {};
var p = new com.example.Person();

所以我发现完全没有必要为 Example 定义一个 ObjectWrap 类。相反,我将它定义为一个简单的对象

v8::Isolate *isolate = v8::Isolate::GetCurrent();
v8::Handle<Object> example = v8::Object::New(isolate);

然后把它传给Person::Init()这样

void addon::Person::Init(v8::Local<v8::Object> nmspace) {
  // ...
  nmspace->Set(Nan::New("Person").ToLocalChecked(), tpl->GetFunction());
}

生成的代码可以在没有任何警告或错误的情况下运行。

于 2016-06-13T16:03:26.563 回答