前言
v8作为js解释器,也提供了对外接口用于绑定c++对象到js中。
这里面比较有名的就属nodejs了。
这里大致讲述如何根据js绑定c++对象。
v8中绑定c++对象
从需求入手。
我们要实现如下的js调用,考虑如何绑定到c++对象
hello()
绑定一个函数到js,这种最简单。
nodejs非常简单。
NODE_SET_METHOD(target, “hello”, method);
熟悉一下里面具体是怎么调用的是很有必要的。
因此我们拆分NODE_SET_METHOD,就是如下的标准v8函数绑定。
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate, method);
v8::Local<v8::Function> fn = t->GetFunction();
v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, "hello");
fn->SetName(fn_name); //这句好像没有用
target->Set(fn_name, fn);
AObject.hello()
解释一下:js中有个对象AObject,AObject有个方法为hello()
首先考虑如何加个对象AObject,本质上是在target中加个AObject的instance
Handle<ObjectTemplate> JSObjTempl = ObjectTemplate::New();
JSObjTempl->Set(String::NewFromUtf8(isolate, "hello"), FunctionTemplate::New(isolate, Method));
target->Set(String::NewFromUtf8(isolate, "AObject"), JSObjTempl->NewInstance());
new hello().world()
解释一下:new hello()生成一个对象,而这个对象里面有个world方法
Local<FunctionTemplate> t = FunctionTemplate::New(isolate, New);
t->SetClassName(String::NewFromUtf8(isolate, "myclass"));
t->InstanceTemplate()->SetInternalFieldCount(1);
Local<ObjectTemplate> JSObjTempl = t->InstanceTemplate();
JSObjTempl->Set(String::NewFromUtf8(isolate, "world"), FunctionTemplate::New(isolate, Method));
target->Set(String::NewFromUtf8(isolate, "hello"), t->GetFunction());
实现上述js还有另外的方法:hello()的时候可以返回一个对象,而返回的对象里面有world方法。
这个就是下面方法的思路
hello().world()
这个和上面的区别在于没有new,所以里面包含的是instance。
void world(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));
}
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
Handle<ObjectTemplate> t = ObjectTemplate::New();
t->Set(String::NewFromUtf8(isolate, "world"), FunctionTemplate::New(isolate, world));
args.GetReturnValue().Set(t->NewInstance());
}
void init(Handle<Object> target) {
NODE_SET_METHOD(target, "hello", Method);
}
综上,我们可以看到,如果js中有new,必然是绑定的函数,如果js直接调用,那存储的一定是instance或者说object