【发布时间】:2018-01-17 13:17:57
【问题描述】:
我有两个简单的类 A 和 B 我试图在 node.js 的本机模块中公开它们。 A 可以直接创建,但B 只能通过调用A::foo() 来创建。
class Internal {};
class B {
public:
Internal internal;
explicit B(Internal internal):internal(internal){}
};
class A {
public:
A() : internal() {};
B foo() { return B(internal); }
private:
Internal internal;
};
我希望能够写作:
const M = require('node_nan_minimal');
const a = new M.A();
const b = a.foo();
为此,我创建了两个从 Nan::ObjectWrap 派生的包装类
class AWrapper : public Nan::ObjectWrap { ... }
class BWrapper : public Nan::ObjectWrap { ... }
每个分别包含A 或B 的实例。有了这些,我可以从 javascript 中创建一个 A 类型的对象,但是我在实现 AWrapper::foo 时遇到了麻烦。
static NAN_METHOD(foo) {
AWrapper* obj = Nan::ObjectWrap::Unwrap<AWrapper>(info.Holder());
B b = obj->a_.foo();
BWrapper * result = new BWrapper(b);
// Something to get a B object to javascript
// ...
// info.GetReturnValue().Set(result->Wrap());
// ...
// doesn't work - so what should it be?
}
我该怎么做才能使这个功能发挥作用?
.cc文件的完整代码是
#include <node.h>
#include <nan.h>
class Internal {
};
class B {
public:
Internal internal;
explicit B(Internal internal):internal(internal){}
};
class A {
public:
A() : internal() {};
B foo() { return B(internal); }
private:
Internal internal;
};
class BWrapper : public Nan::ObjectWrap {
public:
B b_;
explicit BWrapper(B b) : b_(b) {}
~BWrapper() {}
};
class AWrapper : public Nan::ObjectWrap {
public:
A a_;
explicit AWrapper(A a) : a_(a) {}
~AWrapper() {}
static void register_class(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(Nan::New("A").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "foo", foo);
constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
Nan::Set(target, Nan::New("A").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}
private:
static NAN_METHOD(New) {
if (info.IsConstructCall()) {
A a;
AWrapper *obj = new AWrapper(a);
obj->Wrap(info.This());
info.GetReturnValue().Set(info.This());
} else {
const int argc = 1;
v8::Local<v8::Value> argv[argc] = {info[0]};
v8::Local<v8::Function> cons = Nan::New(constructor());
info.GetReturnValue().Set(cons->NewInstance(argc, argv));
}
}
static NAN_METHOD(foo) {
AWrapper* obj = Nan::ObjectWrap::Unwrap<AWrapper>(info.Holder());
B b = obj->a_.foo();
BWrapper * result = new BWrapper(b);
// Something to get a B object to javascript
//...
//info.GetReturnValue().Set(result->Wrap());
}
static inline Nan::Persistent<v8::Function> & constructor() {
static Nan::Persistent<v8::Function> my_constructor;
return my_constructor;
}
};
NAN_MODULE_INIT(InitModule) {
AWrapper::register_class(target);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, InitModule);
该示例的完整存储库可以在 https://github.com/mikeando/node_nan_minimal 找到,您应该能够克隆它,然后使用 npm install 构建。
【问题讨论】:
标签: javascript c++ node.js node.js-nan