nan 入门手册
fengmk2 opened this issue · comments
fengmk2 commented
最近在尝试改进 hsf 的 c++ 模块实现, 将 hessian 1.0 的 encode 和 decode 暴露出来给 js 调用.
因为需要保证 hsf 模块能在node 0.10.x 和 0.11.x 都能正常使用, 那么必须让此 c++ 模块有良好的代码兼容性.
吐血, c++ 新手还要考虑兼容性, 晴天霹雳.
org, 还好发现了 nan: A header file filled with macro and utility goodness for making add-on development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.
示例代码
codes at: nan-example
基本类型
// function showTypes() {}
NAN_METHOD(showTypes) {
NanScope();
// var foo;
// var bar = null;
v8::Local<v8::Value> foo = NanUndefined();
v8::Local<v8::Value> bar = NanNull();
v8::Handle<v8::Value> bar2 = NanNull();
// var t = true;
// var f = false;
v8::Local<v8::Boolean> t = NanTrue();
v8::Local<v8::Boolean> f = NanFalse();
// var v1 = 100;
// var v2 = 1024.123;
// var v3 = 0.123456789;
v8::Local<v8::Number> v1 = NanNew<v8::Number>(100);
v8::Local<v8::Number> v2 = NanNew<v8::Number>(1024.123);
v8::Handle<v8::Number> v3 = NanNew<v8::Number>(0.123456789);
// var s1 = '';
// var s2 = 'hello world';
// var s3 = 'no ascii 还有中文';
v8::Local<v8::String> s1 = NanNew<v8::String>("");
v8::Local<v8::String> s2 = NanNew<v8::String>("hello world");
v8::Local<v8::String> s3 = NanNew<v8::String>("no ascii 还有中文");
// var now = new Date(1399273631054);
double timestamp = 1399273631054;
v8::Local<v8::Date> now = NanNew<v8::Date>(timestamp);
// var result = {};
// result['undefined'] = foo;
// result['null'] = bar;
// result['null2'] = bar2;
// result['true'] = t;
// result['false'] = f;
// result['v1'] = v1;
// result['v2'] = v2;
// result['v3'] = v3;
// result['s1'] = s1;
// result['s2'] = s2;
// result['s3'] = s3;
// result.now = now;
v8::Local<v8::Object> result = NanNew<v8::Object>();
result->Set(NanSymbol("undefined"), foo);
result->Set(NanSymbol("null"), bar);
result->Set(NanSymbol("null2"), bar2);
result->Set(NanSymbol("true"), t);
result->Set(NanSymbol("false"), f);
result->Set(NanSymbol("v1"), v1);
result->Set(NanSymbol("v2"), v2);
result->Set(NanSymbol("v3"), v3);
result->Set(NanSymbol("s1"), s1);
result->Set(NanSymbol("s2"), s2);
result->Set(NanSymbol("s3"), s3);
result->Set(NanSymbol("now"), now);
// var arr = [];
// arr.push(foo);
// arr.push(bar);
// arr.push(bar2);
// arr.push(t);
// arr.push(f);
// arr.push(v1);
// arr.push(v2);
// arr.push(v3);
// arr.push(s1);
// arr.push(s2);
// arr.push(s3);
// arr.push(now);
int index = 0;
v8::Local<v8::Array> arr = NanNew<v8::Array>();
arr->Set(index++, foo);
arr->Set(index++, bar);
arr->Set(index++, bar2);
arr->Set(index++, t);
arr->Set(index++, f);
arr->Set(index++, v1);
arr->Set(index++, v2);
arr->Set(index++, v3);
arr->Set(index++, s1);
arr->Set(index++, s2);
arr->Set(index++, s3);
arr->Set(index++, now);
result->Set(NanSymbol("array"), arr);
result->Set(NanSymbol("array-length"), NanNew<v8::Number>(arr->Length()));
NanReturnValue(result);
}
v8::Local 和 v8::Handle 的区别
v8::XXX 和 v8::XXXObject 的区别
Number vs NumberObject
函数
module.exports
fengmk2 commented
/**
* A JavaScript object (ECMA-262, 4.3.3)
*/
class V8_EXPORT Object : public Value {
public:
bool Set(Handle<Value> key,
Handle<Value> value,
PropertyAttribute attribs = None);
bool Set(uint32_t index, Handle<Value> value);
// Sets a local property on this object bypassing interceptors and
// overriding accessors or read-only properties.
//
// Note that if the object has an interceptor the property will be set
// locally, but since the interceptor takes precedence the local property
// will only be returned if the interceptor doesn't return a value.
//
// Note also that this only works for named properties.
bool ForceSet(Handle<Value> key,
Handle<Value> value,
PropertyAttribute attribs = None);
Local<Value> Get(Handle<Value> key);
Local<Value> Get(uint32_t index);
/**
* Gets the property attributes of a property which can be None or
* any combination of ReadOnly, DontEnum and DontDelete. Returns
* None when the property doesn't exist.
*/
PropertyAttribute GetPropertyAttributes(Handle<Value> key);
bool Has(Handle<Value> key);
bool Delete(Handle<Value> key);
// Delete a property on this object bypassing interceptors and
// ignoring dont-delete attributes.
bool ForceDelete(Handle<Value> key);
bool Has(uint32_t index);
bool Delete(uint32_t index);
bool SetAccessor(Handle<String> name,
AccessorGetterCallback getter,
AccessorSetterCallback setter = 0,
Handle<Value> data = Handle<Value>(),
AccessControl settings = DEFAULT,
PropertyAttribute attribute = None);
// This function is not yet stable and should not be used at this time.
bool SetDeclaredAccessor(Local<String> name,
Local<DeclaredAccessorDescriptor> descriptor,
PropertyAttribute attribute = None,
AccessControl settings = DEFAULT);
void SetAccessorProperty(Local<String> name,
Local<Function> getter,
Handle<Function> setter = Handle<Function>(),
PropertyAttribute attribute = None,
AccessControl settings = DEFAULT);
/**
* Functionality for private properties.
* This is an experimental feature, use at your own risk.
* Note: Private properties are inherited. Do not rely on this, since it may
* change.
*/
bool HasPrivate(Handle<Private> key);
bool SetPrivate(Handle<Private> key, Handle<Value> value);
bool DeletePrivate(Handle<Private> key);
Local<Value> GetPrivate(Handle<Private> key);
/**
* Returns an array containing the names of the enumerable properties
* of this object, including properties from prototype objects. The
* array returned by this method contains the same values as would
* be enumerated by a for-in statement over this object.
*/
Local<Array> GetPropertyNames();
/**
* This function has the same functionality as GetPropertyNames but
* the returned array doesn't contain the names of properties from
* prototype objects.
*/
Local<Array> GetOwnPropertyNames();
/**
* Get the prototype object. This does not skip objects marked to
* be skipped by __proto__ and it does not consult the security
* handler.
*/
Local<Value> GetPrototype();
/**
* Set the prototype object. This does not skip objects marked to
* be skipped by __proto__ and it does not consult the security
* handler.
*/
bool SetPrototype(Handle<Value> prototype);
/**
* Finds an instance of the given function template in the prototype
* chain.
*/
Local<Object> FindInstanceInPrototypeChain(Handle<FunctionTemplate> tmpl);
/**
* Call builtin Object.prototype.toString on this object.
* This is different from Value::ToString() that may call
* user-defined toString function. This one does not.
*/
Local<String> ObjectProtoToString();
/**
* Returns the function invoked as a constructor for this object.
* May be the null value.
*/
Local<Value> GetConstructor();
/**
* Returns the name of the function invoked as a constructor for this object.
*/
Local<String> GetConstructorName();
/** Gets the number of internal fields for this Object. */
int InternalFieldCount();
/** Same as above, but works for Persistents */
V8_INLINE static int InternalFieldCount(
const PersistentBase<Object>& object) {
return object.val_->InternalFieldCount();
}
/** Gets the value from an internal field. */
V8_INLINE Local<Value> GetInternalField(int index);
/** Sets the value in an internal field. */
void SetInternalField(int index, Handle<Value> value);
/**
* Gets a 2-byte-aligned native pointer from an internal field. This field
* must have been set by SetAlignedPointerInInternalField, everything else
* leads to undefined behavior.
*/
V8_INLINE void* GetAlignedPointerFromInternalField(int index);
/** Same as above, but works for Persistents */
V8_INLINE static void* GetAlignedPointerFromInternalField(
const PersistentBase<Object>& object, int index) {
return object.val_->GetAlignedPointerFromInternalField(index);
}
/**
* Sets a 2-byte-aligned native pointer in an internal field. To retrieve such
* a field, GetAlignedPointerFromInternalField must be used, everything else
* leads to undefined behavior.
*/
void SetAlignedPointerInInternalField(int index, void* value);
// Testers for local properties.
bool HasOwnProperty(Handle<String> key);
bool HasRealNamedProperty(Handle<String> key);
bool HasRealIndexedProperty(uint32_t index);
bool HasRealNamedCallbackProperty(Handle<String> key);
/**
* If result.IsEmpty() no real property was located in the prototype chain.
* This means interceptors in the prototype chain are not called.
*/
Local<Value> GetRealNamedPropertyInPrototypeChain(Handle<String> key);
/**
* If result.IsEmpty() no real property was located on the object or
* in the prototype chain.
* This means interceptors in the prototype chain are not called.
*/
Local<Value> GetRealNamedProperty(Handle<String> key);
/** Tests for a named lookup interceptor.*/
bool HasNamedLookupInterceptor();
/** Tests for an index lookup interceptor.*/
bool HasIndexedLookupInterceptor();
/**
* Turns on access check on the object if the object is an instance of
* a template that has access check callbacks. If an object has no
* access check info, the object cannot be accessed by anyone.
*/
void TurnOnAccessCheck();
/**
* Returns the identity hash for this object. The current implementation
* uses a hidden property on the object to store the identity hash.
*
* The return value will never be 0. Also, it is not guaranteed to be
* unique.
*/
int GetIdentityHash();
/**
* Access hidden properties on JavaScript objects. These properties are
* hidden from the executing JavaScript and only accessible through the V8
* C++ API. Hidden properties introduced by V8 internally (for example the
* identity hash) are prefixed with "v8::".
*/
bool SetHiddenValue(Handle<String> key, Handle<Value> value);
Local<Value> GetHiddenValue(Handle<String> key);
bool DeleteHiddenValue(Handle<String> key);
/**
* Returns true if this is an instance of an api function (one
* created from a function created from a function template) and has
* been modified since it was created. Note that this method is
* conservative and may return true for objects that haven't actually
* been modified.
*/
bool IsDirty();
/**
* Clone this object with a fast but shallow copy. Values will point
* to the same values as the original object.
*/
Local<Object> Clone();
/**
* Returns the context in which the object was created.
*/
Local<Context> CreationContext();
/**
* Set the backing store of the indexed properties to be managed by the
* embedding layer. Access to the indexed properties will follow the rules
* spelled out in CanvasPixelArray.
* Note: The embedding program still owns the data and needs to ensure that
* the backing store is preserved while V8 has a reference.
*/
void SetIndexedPropertiesToPixelData(uint8_t* data, int length);
bool HasIndexedPropertiesInPixelData();
uint8_t* GetIndexedPropertiesPixelData();
int GetIndexedPropertiesPixelDataLength();
/**
* Set the backing store of the indexed properties to be managed by the
* embedding layer. Access to the indexed properties will follow the rules
* spelled out for the CanvasArray subtypes in the WebGL specification.
* Note: The embedding program still owns the data and needs to ensure that
* the backing store is preserved while V8 has a reference.
*/
void SetIndexedPropertiesToExternalArrayData(void* data,
ExternalArrayType array_type,
int number_of_elements);
bool HasIndexedPropertiesInExternalArrayData();
void* GetIndexedPropertiesExternalArrayData();
ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
int GetIndexedPropertiesExternalArrayDataLength();
/**
* Checks whether a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
* When an Object is callable this method returns true.
*/
bool IsCallable();
/**
* Call an Object as a function if a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
*/
Local<Value> CallAsFunction(Handle<Value> recv,
int argc,
Handle<Value> argv[]);
/**
* Call an Object as a constructor if a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
* Note: This method behaves like the Function::NewInstance method.
*/
Local<Value> CallAsConstructor(int argc, Handle<Value> argv[]);
static Local<Object> New(Isolate* isolate);
V8_INLINE static Object* Cast(Value* obj);
private:
Object();
static void CheckCast(Value* obj);
Local<Value> SlowGetInternalField(int index);
void* SlowGetAlignedPointerFromInternalField(int index);
};
/**
* An instance of the built-in array constructor (ECMA-262, 15.4.2).
*/
class V8_EXPORT Array : public Object {
public:
uint32_t Length() const;
/**
* Clones an element at index |index|. Returns an empty
* handle if cloning fails (for any reason).
*/
Local<Object> CloneElementAt(uint32_t index);
/**
* Creates a JavaScript array with the given length. If the length
* is negative the returned array will have length 0.
*/
static Local<Array> New(Isolate* isolate, int length = 0);
V8_INLINE static Array* Cast(Value* obj);
private:
Array();
static void CheckCast(Value* obj);
};