现在为我们的V8,实现一些自己的东西吧。
这小节,实现一个alert函数,弹出iphone的系统alertview,并将传递参数中的字符串拼接显示出来。
要动态产生一个函数Function,需要使用函数模板FunctionTemplate。(说到这里,感觉应该先讲一小节Object, Function的才对)
Local<FunctionTemplate> alertTemplate = FunctionTemplate::New(jAlert);
jAlert就是我们用C++代码实现的实际执行者。它需要符合函数指针InvocationCallback的规范。
这是这个函数的声明 Handle<Value> jAlert(const Arguments& args);
然后我们需要把alertTemplate加入到context中,context只能关联对象Object和对象模板ObjectTemplate,而ObjectTemplate才可以关联FunctionTemplate,所以我们还需要创建一个ObjectTemplate。再把ObjectTemplate和context关联。
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("alert"), alertTemplate);
Persistent<Context> context = Context::New(NULL, global);
这样就差不多了,补上新的js脚本字符串就可以了。
Handle<String> source = String::New("alert('hello ','v8 ',123,'alert ');");
因为在jAlert中,筛选了是否为字符串,所以弹出的提示文本为“hello v8 alert”
下面是这个例子的代码。
Handle<Value> jAlert(const Arguments& args)
{
NSMutableString *argString = [NSMutableString stringWithString:@""];
for (int i = 0; i < args.Length(); i++)
{
Local<Value> jArgValue = args[i];
if (jArgValue->IsString())
{
String::Utf8Value utfStr(jArgValue);
NSString *argStr = [NSString stringWithCString:*utfStr
encoding:NSUTF8StringEncoding];
[argString appendString:argStr];
}
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"alert"
message:argString
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
return Null();
}
- (void)handler
{
HandleScope handle_scope;
Handle<ObjectTemplate> global = ObjectTemplate::New();
Local<FunctionTemplate> alertTemplate = FunctionTemplate::New(jAlert);
global->Set(String::New("alert"), alertTemplate);
Persistent<Context> context = Context::New(NULL, global);
Context::Scope context_scope(context);
Handle<String> source = String::New("alert('hello','v8',123,'alert');");
Handle<Script> script = Script::Compile(source);
Handle<Value> result = script->Run();
context.Dispose();
}
现在可以自己添加想要的功能函数了。但是,那些需要保存一些变量用来计算,也就是类成员变量的事情应该怎么做呢?
下一节,就开始学习,怎样将JS类和一个C++类关联起来。