我正在嘗試開發更好地理解開發使用C++包裝器的Nodejs模塊所需的技術。我正在通過儘可能多的信息進行工作,例如Nodejs Documentation。爲推動我的理解我寫設置,可以以類似的方式被用於一個模塊的NodeJS的挑戰:使用C++包裝將參數傳遞給Nodejs模塊?
var addon = require('./fruit.js');
var apple = new addon.Fruit(5,7);
var pear = new addon.Fruit(3,6);
console.log("Apple: weight = " + apple.getWeight() + " calories = "
+ apple.getCalories());
var bunch = new addon.Grapes(50, 2, 2);
console.log("Calories of a grape: " + bunch.getCalories());
console.log("Total weight of grapes: " + bunch.getBunchWeight());
其中fruit.js是:
function Fruit(weight, calories) {
this.weight = weight;
this.calories = calories;
}
Fruit.prototype.getWeight = function() {
return this.weight;
};
Fruit.prototype.getCalories = function() {
return this.calories;
};
Grapes.prototype = new Fruit();
Grapes.prototype.constructor=Grapes;
function Grapes(number, weight, calories) {
this.number=number;
this.weight=weight;
this.calories=calories;
}
Grapes.prototype.getTotalWeight = function() {
return this.number * this.weight;
}
exports.Fruit = Fruit;
exports.Grapes = Grapes;
要開發一個模塊的NodeJS與C++包裝我通過Stack Overflow張貼工作,但是當我添加參數到繼承類參數不傳遞給基類。我嘗試了很多解決方案,但是我覺得我對功能的理解就是我錯了。代碼如下:
mymod_wrap.h
#ifndef MYOBJECT_WRAP_H
#define MYOBJECT_WRAP_H
#include <node.h>
using namespace v8;
class Fruit : public node::ObjectWrap {
public:
Fruit();
~Fruit();
static Persistent<FunctionTemplate> fruit_template;
static void Init(Handle<Object> exports);
static Handle<Value> New(const Arguments& args);
static Handle<Value> GetWeight(const Arguments& args);
static Handle<Value> GetCalories(const Arguments& args);
private:
double weight_;
double calories_;
};
class Grapes : public node::ObjectWrap {
public:
Grapes();
~Grapes();
static Persistent<FunctionTemplate> grapes_template;
static void Init(Handle<Object> exports);
static Handle<Value> New(const Arguments& args);
static Handle<Value> GetBunchWeight(const Arguments& args);
private:
int number_;
};
#endif
mymod_wrap.cc
#include <node.h>
#include "mymod_wrap.h"
using namespace v8;
Fruit::Fruit() {};
Fruit::~Fruit() {};
void Fruit::Init(Handle<Object> exports) {
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
fruit_template = Persistent<FunctionTemplate>::New(tpl);
fruit_template->InstanceTemplate()->SetInternalFieldCount(1);
fruit_template->SetClassName(String::NewSymbol("Fruit"));
NODE_SET_PROTOTYPE_METHOD(fruit_template, "getWeight", GetWeight);
NODE_SET_PROTOTYPE_METHOD(fruit_template, "getCalories", GetCalories);
exports->Set(String::NewSymbol("Fruit"), fruit_template->GetFunction());
}
Handle<Value> Fruit::New(const Arguments& args) {
HandleScope scope;
Fruit* obj = new Fruit(); // Conventional C++ Call see notes
obj->weight_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
obj->calories_ = args[1]->IsUndefined() ? 0 : args[1]->NumberValue();
obj->Wrap(args.This());
return args.This();
}
Handle<Value> Fruit::GetWeight(const Arguments& args) {
HandleScope scope;
Fruit* obj = ObjectWrap::Unwrap<Fruit>(args.This());
return scope.Close(Number::New(obj->weight_));
}
Handle<Value> Fruit::GetCalories(const Arguments& args) {
HandleScope scope;
Fruit* obj = ObjectWrap::Unwrap<Fruit>(args.This());
return scope.Close(Number::New(obj->calories_));
}
Persistent<FunctionTemplate> Fruit::fruit_template;
Grapes::Grapes() {};
Grapes::~Grapes() {};
void Grapes::Init(Handle<Object> exports) {
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
grapes_template = Persistent<FunctionTemplate>::New(tpl);
grapes_template->Inherit(Fruit::fruit_template);
grapes_template->InstanceTemplate()->SetInternalFieldCount(1);
grapes_template->SetClassName(String::NewSymbol("Grapes"));
NODE_SET_PROTOTYPE_METHOD(grapes_template, "getBunchWeight", GetBunchWeight);
exports->Set(String::NewSymbol("Grapes"), grapes_template->GetFunction());
}
Handle<Value> Grapes::New(const Arguments& args){
HandleScope scope;
Grapes* obj = new Grapes();
obj->number_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
/* the above works but need to pass args[1], args[2] to */
/* "weight_" and "calories_" in the base class ? */
obj->Wrap(args.This());
return args.This();
}
Handle<Value> Grapes::GetBunchWeight(const Arguments& args) {
HandleScope scope;
Grapes* obj = ObjectWrap::Unwrap<Grapes>(args.This());
/* Need to unwrap the base object to get "weight_" */
/* multiply with "number_" to get the total weight of the bunch */
return scope.Close(Number::New(/* return calculated total weight */));
}
Persistent<FunctionTemplate>Grapes::grapes_template;
mymod.cc
#include <node.h>
#include "mymod_wrap.h"
using namespace v8;
void InitAll(Handle<Object> exports) {
Fruit::Init(exports);
Grapes::Init(exports);
}
NODE_MODULE(fruit, InitAll)
我在代碼中添加了一些註釋,以表明我認爲問題出在哪裏。
感謝任何指向我錯誤的地方。
感謝您對我的問題的回覆。我是JS新手,因此發現你對背景中發生的事情的解釋非常有幫助。我完成了C++實現的指導,並且對JS有了更清晰的理解,一切都正常。謝謝你的幫助。 – David 2013-04-23 17:39:45