写这篇文章前,大家可以在Google上找到很多Google v8基础入门的文章,例如:
IBM DeveloperWorks中国
https://www.ibm.com/developerworks/cn/opensource/os-cn-v8engine/
Legend(谭海燕)的专栏
http://blog.csdn.net/feiyinzilgd/article/details/8248448
headool的专栏
http://blog.csdn.net/headool/article/list/2
等等…
但之前的一些基础教程由于v8的版本有些低,在新版的v8接口下编绎通不过,所以在此就整理了一下,自己记录学习了,理论相关的知识我就不整理,上面的博文说得比较详细了,直接上代码
全局变量,供JS访问
static int globalValue = 0;
static Isolate *globalIsolate = NULL;
void globalGetter(Local<String> property, PropertyCallbackInfo<Value>& info)
{
info.GetReturnValue().Set(v8::Integer::New(globalIsolate, globalValue));
printf("js read \"globalValue\"\n");
}
void globalSetter(Local<String> property, Local<Value> value, const PropertyCallbackInfo<void>& info)
{
globalValue = value->Int32Value();
printf("js change \"globalValue: %d\"\n", globalValue);
}
int main(int argc, const char * argv[])
{
v8::V8::InitializeICU();
v8::V8::Initialize();
globalIsolate = Isolate::New();
Isolate::Scope isolate_scope(globalIsolate);
HandleScope handle_scope(globalIsolate);
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(globalIsolate);
//全局变量,通过Getter,Setter方法访问和设置
global->SetAccessor(v8::String::NewFromUtf8(globalIsolate, "globalValue"), (AccessorGetterCallback)globalGetter, (AccessorSetterCallback)globalSetter);
Local<Context> context = Context::New(globalIsolate, NULL, global);
Context::Scope context_scope(context);
//编写JS源代码,编绎执行
Local<String> source = String::NewFromUtf8(globalIsolate, "var tmpValue = globalValue; globalValue = 21; ");
Local<Script> script = Script::Compile(source);
Local<Value> result = script->Run();
String::Utf8Value utf8(result);
printf("Script Run Result: %s\n", *utf8);
v8::V8::Dispose();
return 0;
}
输出
js read "globalValue"
js change "globalValue: 21"
Script Run Result: 21
全局函数,供JS调用
void globalFun(const v8::FunctionCallbackInfo<Value> &args)
{
printf("js call C++ \"globalFun\"\n");
}
int main(int argc, const char * argv[])
{
//省略部份声明代码,参考上面
Local<FunctionTemplate> globalFunTemplate = v8::FunctionTemplate::New(globalIsolate, (FunctionCallback)globalFun);
global->Set(v8::String::NewFromUtf8(globalIsolate, "globalFun"), globalFunTemplate);
Local<String> source = String::NewFromUtf8(globalIsolate, "globalFun();");
Local<Script> script = Script::Compile(source);
Local<Value> result = script->Run();
}
输出:
js call C++ "globalFun"
JS访问C++类及方法
class Person{
private:
String::Utf8Value *firstName;
String::Utf8Value *lastName;
public:
Person(Handle<v8::Value> firstValue, Handle<v8::Value> LastValue){
this->firstName = new String::Utf8Value(firstValue);
this->lastName = new String::Utf8Value(LastValue);
}
~Person(){
delete firstName;
delete lastName;
}
void sayHello(){
printf("Hello, My Name is: \"%s %s\"\n", **firstName, **lastName);
}
};
//JS访问Person.sayHell转换函数
void Person_SayHello(const v8::FunctionCallbackInfo<Value> &args)
{
Local<Object> self = args.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void *ptr = wrap->Value();
static_cast<Person*>(ptr)->sayHello();
}
//JS创建Person转换函数
void createPerson(const v8::FunctionCallbackInfo<Value> &args)
{
if (args.Length() >= 2){
Local<Object> self = args.Holder();
Person *person = new Person(args[0], args[1]);
self->SetInternalField(0, External::New(globalIsolate, person));
args.GetReturnValue().Set(self);
}
}
int main(int argc, const char * argv[])
{
//省略部份声明代码,参考上面
v8::Local<FunctionTemplate> personClass = v8::FunctionTemplate::New(globalIsolate, (FunctionCallback)createPerson);
personClass->SetClassName(v8::String::NewFromUtf8(globalIsolate, "Person"));
v8::Handle<ObjectTemplate>p_Prototype = personClass->PrototypeTemplate();
p_Prototype->Set(String::NewFromUtf8(globalIsolate, "sayHello"), FunctionTemplate::New(globalIsolate, Person_SayHello));
v8::Handle<ObjectTemplate> personInst = personClass->InstanceTemplate();
personInst->SetInternalFieldCount(1);
global->Set(v8::String::NewFromUtf8(globalIsolate, "Person"), personClass);
Local<String> source = String::NewFromUtf8(globalIsolate, "var p = new Person('Kevin', 'Lu'); p.sayHello();");
Local<Script> script = Script::Compile(source);
Local<Value> result = script->Run();
}
输出:
Hello, My Name is: "Kevin Lu"
C++访问JS
void testCallJS()
{
v8::Isolate *callJSISolate = v8::Isolate::New();
v8::Isolate::Scope isolate_scope(callJSISolate);
HandleScope handle_scope(callJSISolate);
v8::Handle<Context> context = v8::Context::New(callJSISolate);
v8::Context::Scope contextScope(context);
//JS创建Person对象,并添加getName方法,返回name
v8::Local<String> source = String::NewFromUtf8(callJSISolate, "function Person() { this.name = 'Kevin'; } Person.prototype.getName = function () { return this.name; }; var p = new Person();");
v8::Local<Script> script = v8::Script::Compile(source);
script->Run();
v8::Handle<Value> data_p = context->Global()->Get(String::NewFromUtf8(callJSISolate, "p"));
v8::Handle<Object> object_p = Handle<Object>::Cast(data_p);
v8::Handle<Function> getName = Handle<Function>::Cast(object_p->Get(String::NewFromUtf8(callJSISolate, "getName")));
Handle<Value> value = getName->Call(object_p, 0, NULL);
String::Utf8Value utf8(value);
printf("call js function result: %s\n", *utf8);
}
输出:
call js function result: Kevin
上面例子源代码:点这里
有了这些基础的知识,大家可以尝试写一些应用了,更多的知识可以直接去参考基于Google v8的Node.js、io.js、fibjs的源代码