2011
Dec
21

前言 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了。

  1. Handle<ObjectTemplate> global;
  2. global = ObjectTemplate::New();
  3. //指定 mktime, c語言中執行的function也叫 mktime
  4. global->Set(String::New("mktime"), FunctionTemplate::New(mktime));
  5.  
  6. Handle<Context> context;
  7. //將 ObjectTemplate 傳給 Context
  8. 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 程式碼,月份的部份就要自已修改囉。

  1. Handle<Value> mktime(const Arguments& args)
  2. {
  3. unsigned int hours = args[0]->Uint32Value();
  4. unsigned int minutes = args[1]->Uint32Value();
  5. unsigned int seconds = args[2]->Uint32Value();
  6. unsigned int month = args[3]->Uint32Value();
  7. unsigned int day = args[4]->Uint32Value();
  8. unsigned int year = args[5]->Uint32Value();
  9. time_t t;
  10. struct tm timeinfo;
  11.  
  12. memset(&timeinfo, 0, sizeof(tm));
  13. timeinfo.tm_sec = seconds;
  14. timeinfo.tm_min = minutes;
  15. timeinfo.tm_hour = hours;
  16. timeinfo.tm_mday = day;
  17. timeinfo.tm_mon = month-1;
  18. timeinfo.tm_year = year-1900 ;
  19. t = mktime(&timeinfo);
  20. return Uint32::New(t);
  21. }
  22.  

C code main function

  1. #include <iostream>
  2. #include "v8.h"
  3. #include <time.h>
  4. Handle<Value> mktime(const Arguments& args);
  5. int main (){
  6. Handle<ObjectTemplate> global;
  7. HandleScope handle_scope;
  8. Handle<Context> context;
  9.  
  10. global = ObjectTemplate::New();
  11. global->Set(String::New("mktime"), FunctionTemplate::New(mktime));
  12.  
  13. context= Context::New(NULL,global);
  14. Context::Scope context_scope(context);
  15. //讀取 makeFunction.js ,並存到 String
  16. Handle<v8::String> source = ReadFile("makeFunction.js");
  17. //Compile
  18. Handle<Script> script = Script::Compile(source);
  19. Handle<Value> result = script->Run();
  20.  
  21. //取得變數 result
  22. String::Utf8Value str(result);
  23. script = Script::Compile(String::New("result"));
  24. result = script->Run();
  25. cout << *String::Utf8Value(result);
  26. return 0;
  27. }
  28.  

js code

現在就寫個 javascript 來測試一下 mktime功能

makeFunction.js
  1. var result = mktime(8,0,0,12,25,2011);
  2. //output : 1324771200

回應 (Leave a comment)