前言 JS Extension
本课程,教你怎么增加 Javscript 的 function,将自已常用的功能,用c code写出来, 之后我就先称之为 js extension,现在我们就来开发 js extension吧。
读取 JS file
再写 js extension之前,再重覆说明一下,如果读取 Javascript File,可以参考上一课的内容 Script Run2 。
简单讲就是把 js 的了语法存到 v8::String 里,当然你要怎么去读取 JS File 方法就很多种了,我不必再说明。
实作一个 mktime
Javascript 没有 mktime的function,我们就先实作一个 mktime js estension吧!!
ObjectTemplate : 定义一个 function 给 Javascript 呼叫
建立一个 ObjectTemplate , 我们要先给 ObjectTemplate 指定一个 function 名称,第二个参数是指定 C Code 中「执行的function」,接者再将新的 ObjectTemplate 传送给 Context ( Context 就很像是浏览器的意思),所以我们现在就把 js extension 挂上了浏览器,之后执行 JS 编译时,就可以正常使用这个 function了。
- Handle<ObjectTemplate> global;
- global = ObjectTemplate::New();
- //指定 mktime, c语言中执行的function也叫 mktime
- global->Set(String::New("mktime"), FunctionTemplate::New(mktime));
- Handle<Context> context;
- //将 ObjectTemplate 传给 Context
- context= Context::New(NULL,global);
用 c语言写一个 mktime function
建立一个 mktime function,参数这里使用 Arguments的方式让JS传进来,这样可以无限次的增加参数数量,反正 JS 没有变数型态的问题,所以参数不用指定 char or int 等型态,回传值型态为 Value ,Value 在 v8 中是全有变数型态的父类别,所以可以处理任何的变数型态,这里的参数与回传值只能用这两个值,记住不能用别的数值,否则进编译都过不了,这是为了配合 Javascript 的变数值。
记得在 get timestamp 时,时间是从 1900/01/01 开始计算的,所以传入的日期要减掉 1900 ,月份在 c 语言中是从 0 开始计( 0 代表一月,11代表12月),所以月份也要记得减 1 ,然后说 Javascript 的月份也是从 0开始计,不过我还是习惯用1代表一月份啦,所以这里我还是有减1,如果你需要配合旧的 Javascript 程式码,月份的部份就要自已修改罗。
- Handle<Value> mktime(const Arguments& args)
- {
- unsigned int hours = args[0]->Uint32Value();
- unsigned int minutes = args[1]->Uint32Value();
- unsigned int seconds = args[2]->Uint32Value();
- unsigned int month = args[3]->Uint32Value();
- unsigned int day = args[4]->Uint32Value();
- unsigned int year = args[5]->Uint32Value();
- time_t t;
- struct tm timeinfo;
- memset(&timeinfo, 0, sizeof(tm));
- timeinfo.tm_sec = seconds;
- timeinfo.tm_min = minutes;
- timeinfo.tm_hour = hours;
- timeinfo.tm_mday = day;
- timeinfo.tm_mon = month-1;
- timeinfo.tm_year = year-1900 ;
- t = mktime(&timeinfo);
- return Uint32::New(t);
- }
C code main function
- #include <iostream>
- #include "v8.h"
- #include <time.h>
- Handle<Value> mktime(const Arguments& args);
- int main (){
- Handle<ObjectTemplate> global;
- HandleScope handle_scope;
- Handle<Context> context;
- global = ObjectTemplate::New();
- global->Set(String::New("mktime"), FunctionTemplate::New(mktime));
- context= Context::New(NULL,global);
- Context::Scope context_scope(context);
- //读取 makeFunction.js ,并存到 String
- Handle<v8::String> source = ReadFile("makeFunction.js");
- //Compile
- Handle<Script> script = Script::Compile(source);
- Handle<Value> result = script->Run();
- //取得变数 result
- String::Utf8Value str(result);
- script = Script::Compile(String::New("result"));
- result = script->Run();
- cout << *String::Utf8Value(result);
- return 0;
- }
js code
现在就写个 javascript 来测试一下 mktime功能
- var result = mktime(8,0,0,12,25,2011);
- //output : 1324771200