青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數(shù)據(jù)加載中……

在C++中應(yīng)用Google Chrome腳本引擎——V8

原文地址:http://www.codeproject.com/KB/library/Using_V8_Javascript_VM.aspx

clip_image001

介紹

誰不想知道虛擬機(jī)是怎樣工作的?不過,比起自己寫一個虛擬機(jī),更好的辦法是使用大公司的產(chǎn)品。在這篇文章中,我將介紹如何在你的程序中使用V8——谷歌瀏覽器(Chrome)所使用的開源JavaScript引擎。

背景

這里的代碼使用V8作為嵌入庫來執(zhí)行JavaScript代碼。要取得庫源碼和其它信息,可以瀏覽V8開發(fā)者頁面。想有效地應(yīng)用V8,你需要了解C/C++JavaScript

使用

我們來看看演示中有哪些東西:

·                     如何使用V8API來執(zhí)行JavaScript腳本。

·                     如何存取腳本中的整數(shù)和字符串。

·                     如何建立可被腳本調(diào)用的自定義函數(shù)。

·                     如何建立可被腳本調(diào)用的自定義類。

首先,我們一起了解一下怎樣初始化V8。這是嵌入V8引擎的簡單例子:

1.                #include <v8.h>

2.                using namespace v8;

3.                int main(int argc, char* argv[]) {

4.                  // Create a stack-allocated handle scope.

5.                  HandleScope handle_scope;

6.                  // Create a new context.

7.                  Handle<Context> context = Context::New();

8.                  // Enter the created context for compiling and

9.                  // running the hello world script.

10.              Context::Scope context_scope(context);

11.              // Create a string containing the JavaScript source code.

12.              Handle<String> source = String::New("'Hello' + ', World!'");

13.              // Compile the source code.

14.              Handle<Script> script = Script::Compile(source);

15.              // Run the script to get the result.

16.              Handle<Value> result = script->Run();

17.              // Convert the result to an ASCII string and print it.

18.              String::AsciiValue ascii(result);

19.              printf("%s ", *ascii);

20.              return 0;

21.            }

好了,不過這還不能說明怎樣讓我們控制腳本中的變量和函數(shù)。

全局模型(The Global Template

首先,我們需要一個全局模型來掌控我們所做的修改:

1.                v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();

這里建立了一個新的全局模型來管理我們的上下文(context)和定制。在V8里,每個上下文是分開的,它們有自己的全局模型。一個上下文就是一個獨(dú)立的執(zhí)行環(huán)境,相互之間沒有關(guān)聯(lián),JavaScript運(yùn)行于其中一個實(shí)例之中。

自定義函數(shù)

接下來,我們加入一個名為"plus"的自定義函數(shù):

1.                // plus function implementation - Add two numbers

2.                v8::Handle<v8::Value> Plus(const v8::Arguments& args)

3.                {

4.                    unsigned int A = args[0]->Uint32Value();

5.                    unsigned int B = args[1]->Uint32Value();

6.                    return v8_uint32(A +  B);

7.                }

8.                //...

9.                //associates plus on script to the Plus function

10.            global->Set(v8::String::New("plus"), v8::FunctionTemplate::New(Plus));

自定義函數(shù)必須以const v8::Arguments&作為參數(shù)并返回v8::Handle<v8::Value>。我們把這個函數(shù)加入到模型中,關(guān)聯(lián)名稱"plus"到回調(diào)Plus。現(xiàn)在,在腳本中每次調(diào)用"plus",我們的Plus函數(shù)就會被調(diào)用。這個函數(shù)只是返回兩個參數(shù)的和。

現(xiàn)在我們可以在JavaScript里使用這個自定義函數(shù)了:

plus(120,44); 

在腳本里也可以得到函數(shù)的返回值:

x = plus(1,2);

if( x == 3){

   // do something important here!

}

訪問器(Accessor)——存取腳本中的變量

現(xiàn)在,我們可以建立函數(shù)了...不過如果我們可以在腳本外定義一些東西豈不是更酷?Let's do it! V8里有個東東稱為存取器(Accessor),使用它,我們可以關(guān)聯(lián)一個名稱到一對Get/Set函數(shù)上,V8會用它來存取腳本中的變量。

1.                global->SetAccessor(v8::String::New("x"), XGetter, XSetter);

這行代碼關(guān)聯(lián)名稱"x"XGetterXSetter函數(shù)。這樣在腳本中每次讀取到"x"變量時都會調(diào)用XGetter,每次更新"x"變量時會調(diào)用XSetter。下面是這兩個函數(shù)的代碼:

1.                //the x variable!

2.                int x;

3.                //get the value of x variable inside javascript

4.                static v8::Handle<v8::Value> XGetter( v8::Local<v8::String> name,

5.                                  const v8::AccessorInfo& info) {

6.                  return  v8::Number::New(x);

7.                }

8.                //set the value of x variable inside javascript

9.                static void XSetter( v8::Local<v8::String> name,

10.                   v8::Local<v8::Value> value, const v8::AccessorInfo& info) {

11.              x = value->Int32Value();

12.            }

XGetter里我們把"x"轉(zhuǎn)換成V8喜歡的數(shù)值類型。XSetter里,我們把傳入的參數(shù)轉(zhuǎn)換成整數(shù),Int32Value是基本類型轉(zhuǎn)換函數(shù)的一員,還有NumberValue對應(yīng)doubleBooleanValue對應(yīng)bool,等。

現(xiàn)在,我們可以為字符串做相同的操作:

1.                //the username accessible on c++ and inside the script

2.                char username[1024];

3.                //get the value of username variable inside javascript

4.                v8::Handle<v8::Value> userGetter(v8::Local<v8::String> name,

5.                           const v8::AccessorInfo& info) {

6.                    return v8::String::New((char*)&username,strlen((char*)&username));

7.                }

8.                //set the value of username variable inside javascript

9.                void userSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value,

10.                const v8::AccessorInfo& info) {

11.                v8::Local<v8::String> s = value->ToString();

12.                s->WriteAscii((char*)&username);

13.            }

對于字符串,有一點(diǎn)點(diǎn)不同,"userGetter"XGetter做的一樣,不過userSetter要先用ToString方法取得內(nèi)部字符串,然后用WriteAscii函數(shù)把內(nèi)容寫到我們指定的內(nèi)存中。現(xiàn)在,加入存取器:

1.                //create accessor for string username

2.                global->SetAccessor(v8::String::New("user"),userGetter,userSetter);

打印輸出

"print"函數(shù)是另一個自定義函數(shù),它通過"printf"輸出所有的參數(shù)內(nèi)容。和之前的"plus"函數(shù)一樣,我們要在全局模型中注冊這個函數(shù):

1.                //associates print on script to the Print function

2.                global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print));

實(shí)現(xiàn)"print"函數(shù)

1.                // The callback that is invoked by v8 whenever the JavaScript 'print'

2.                // function is called. Prints its arguments on stdout separated by

3.                // spaces and ending with a newline.

4.                v8::Handle<v8::Value> Print(const v8::Arguments& args) {

5.                    bool first = true;

6.                    for (int i = 0; i < args.Length(); i++)

7.                    {

8.                        v8::HandleScope handle_scope;

9.                        if (first)

10.                    {

11.                        first = false;

12.                    }

13.                    else

14.                    {

15.                        printf(" ");

16.                    }

17.                    //convert the args[i] type to normal char* string

18.                    v8::String::AsciiValue str(args[i]);

19.                    printf("%s", *str);

20.                }

21.                printf(" ");

22.                //returning Undefined is the same as returning void...

23.                return v8::Undefined();

24.            }

這里,為每個參數(shù)都構(gòu)建了v8::String::AsciiValue對象:數(shù)據(jù)的char*表示。通過它,我們就可以把所有類型都轉(zhuǎn)換成字符串并打印出來。

JavaScript演示

在演示程序里,我們有一個簡單的JavaScript腳本,調(diào)用了迄今為止我們建立的所有東西:

print("begin script");

print(script executed by  + user);

if ( user == "John Doe"){

    print("\tuser name is invalid. Changing name to Chuck Norris");

    user = "Chuck Norris";

}

print("123 plus 27 = " + plus(123,27));

x = plus(3456789,6543211);

print("end script");

 

存取C++對象

clip_image002

為我們的類準(zhǔn)備環(huán)境

如果用C++把一個類映射到JavaScript中去?放一個演示用的類上來先:

1.                //Sample class mapped to v8

2.                class Point

3.                {

4.                public:

5.                    //constructor

6.                    Point(int x, int y):x_(x),y_(y){}

7.                 

8.                    //internal class functions

9.                    //just increment x_

10.                void Function_A(){++x_;    }

11.             

12.                //increment x_ by the amount

13.                void Function_B(int vlr){x_+=vlr;}

14.             

15.                //variables

16.                int x_;

17.            };

為了把這個類完全嵌入腳本中,我們需要映射類成員函數(shù)和類成員變量。第一步是在我們的上下文中映射一個類模型(class template):

1.                Handle<FunctionTemplate> point_templ = FunctionTemplate::New();

2.                point_templ->SetClassName(String::New("Point"));

我們建立了一個"函數(shù)"模型[FunctionTemplate],但這里應(yīng)該把它看成類。

然后,我們通過原型模型(Prototype Template)加入內(nèi)建的類方法:

1.                Handle<ObjectTemplate> point_proto = point_templ->PrototypeTemplate();

2.                point_proto->Set("method_a", FunctionTemplate::New(PointMethod_A));

3.                point_proto->Set("method_b", FunctionTemplate::New(PointMethod_B));

接下來,類有了兩個方法和對應(yīng)的回調(diào)。但它們目前只在原型中,沒有類實(shí)例訪問器我們還不能使用它們。

1.                Handle<ObjectTemplate> point_inst = point_templ->InstanceTemplate();

2.                point_inst->SetInternalFieldCount(1);

SetInternalFieldCount函數(shù)為C++類建立一個空間(后面會用到)

現(xiàn)在,我們有了類實(shí)例,加入訪問器以訪問內(nèi)部變量:

1.                point_inst->SetAccessor(String::New("x"), GetPointX, SetPointX);

接著,土壤準(zhǔn)備好了,開始播種:

1.                Point* p = new Point(0, 0);

新對象建立好了,目前只能在C++中使用,要放到腳本里,我們還要下面的代碼:

1.                Handle<Function> point_ctor = point_templ->GetFunction();

2.                Local<Object> obj = point_ctor->NewInstance();

3.                obj->SetInternalField(0, External::New(p));

好了,GetFunction返回一個point構(gòu)造器(JavaScript方面), 通過它,我們可以用NewInstance生成一個新的實(shí)例。然后,用Point對象指針設(shè)置我們的內(nèi)部域(我們前面用SetInternalFieldCount建立的空間)JavaScript可以通過這個指針存取對象。

還少了一步,我們只有類模型和實(shí)例,但還缺一個名字來存取它:

1.                context->Global()->Set(String::New("point"), obj);

JavaScript里訪問類方法

最后,我們還要解釋一下怎樣在Point類中訪問Function_A...

讓我們看看PointMethod_A回調(diào):

1.                Handle<Value> PointMethod_A(const Arguments& args)

2.                {

3.                    Local<Object> self = args.Holder();

4.                    Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));

5.                    void* ptr = wrap->Value();

6.                    static_cast<Point*>(ptr)->Function_A();

7.                    return Integer::New(static_cast<Point*>(ptr)->x_);

8.                }

和普通訪問器一樣,我們必須處理參數(shù)。要訪問我們的類,必須從內(nèi)部域(第一個)中取得類指針。把內(nèi)部域映射到"wrap"之后,我們使用它的"value"方法取得類指針。

其它

希望這篇文章對你有所幫助,如果發(fā)現(xiàn)文章有誤,請不吝賜教。

Google的V8參考文檔

許可

This article, along with any associated source code and files, is licensed under A Public Domain dedication

關(guān)于作者

GabrielWF

posted on 2010-05-17 12:25 肥仔 閱讀(6707) 評論(1)  編輯 收藏 引用 所屬分類: 腳本語言

評論

# re: 在C++中應(yīng)用Google Chrome腳本引擎&mdash;&mdash;V8  回復(fù)  更多評論   

怎樣輸出中文?
2010-11-10 17:06 | tttt
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日产在线观看| 午夜精品成人在线| 香蕉久久夜色精品国产| 亚洲视频在线观看| 日韩亚洲不卡在线| 亚洲毛片在线| 亚洲综合国产激情另类一区| 亚洲在线视频| 久久久精品动漫| 欧美激情一区二区三区全黄| 亚洲狼人精品一区二区三区| 午夜精品电影| 欧美二区乱c少妇| 欧美色视频日本高清在线观看| 亚洲麻豆视频| 久久成人精品无人区| 欧美电影在线观看完整版| 国产精品欧美久久| 韩国三级电影久久久久久| 亚洲三级免费| 久久国产婷婷国产香蕉| 亚洲黄色免费电影| 日韩天堂av| 久久精品国产96久久久香蕉| 欧美成人首页| 国产主播精品| 亚洲欧美另类久久久精品2019| 麻豆精品视频在线| 亚洲一区二区三区精品视频| 久久亚洲一区二区| 国产欧美精品| 在线亚洲高清视频| 欧美福利在线观看| 欧美一区二区三区精品| 欧美日韩三级一区二区| 在线观看成人小视频| 亚洲欧美日韩在线| 亚洲精品一区二区三区婷婷月| 久久福利资源站| 国产精品一二三四| 亚洲香蕉伊综合在人在线视看| 久久综合给合久久狠狠狠97色69| 亚洲一区二区网站| 国产精品福利影院| 亚洲一区网站| 一区二区三区你懂的| 欧美日韩一卡| 亚洲婷婷国产精品电影人久久| 亚洲第一网站免费视频| 欧美极品一区| 99re66热这里只有精品4| 久久成人精品视频| 亚洲一区二区三区四区视频| 欧美日韩视频| 正在播放亚洲一区| 亚洲精品久久久久久一区二区 | 一本色道久久88亚洲综合88| 老色批av在线精品| 久久精品国产亚洲a| 国产一区二区三区在线观看精品 | 亚洲欧美日韩综合国产aⅴ| 亚洲毛片视频| 国产精品高潮视频| 欧美一级黄色网| 亚洲一区二区三区在线看 | 国产亚洲精品7777| 久久精品国产亚洲a| 欧美伊人久久| 一区二区三区在线免费视频| 久久夜色精品国产噜噜av| 久久国产精品久久w女人spa| 韩国一区二区在线观看| 欧美jjzz| 欧美区一区二| 午夜伦欧美伦电影理论片| 亚洲免费影视第一页| 国产一区二区三区视频在线观看 | 欧美久久久久中文字幕| 这里只有精品视频在线| 亚洲午夜电影网| 国产一区视频在线看| 欧美第一黄色网| 欧美日韩xxxxx| 欧美亚洲一区二区在线| 久久琪琪电影院| 中文欧美日韩| 久久av二区| 99re国产精品| 欧美一区二区三区免费观看视频| 伊人影院久久| 亚洲视频免费看| 精品福利免费观看| 夜夜精品视频一区二区| 国产深夜精品福利| 亚洲国产精品电影| 国产农村妇女毛片精品久久麻豆| 免费久久99精品国产自在现线| 欧美日韩国产综合网| 久久激五月天综合精品| 亚洲第一精品久久忘忧草社区| 欧美激情精品久久久久久黑人 | 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 亚洲免费电影在线| 亚洲欧美一区二区原创| 亚洲日韩欧美视频| 性欧美xxxx视频在线观看| 日韩一区二区精品在线观看| 亚洲欧美国产高清va在线播| 亚洲精品欧美日韩| 久久精品国产免费观看| 亚洲欧美日产图| 欧美α欧美αv大片| 久久九九国产精品| 国产精品乱人伦一区二区| 亚洲第一页在线| 亚洲电影第1页| 欧美在线视频导航| 欧美亚洲综合网| 国产精品高潮久久| 亚洲人成在线观看一区二区| 尤物yw午夜国产精品视频| 亚洲欧美区自拍先锋| 亚洲一区二区在线视频| 欧美激情第五页| 亚洲第一区在线观看| 亚洲国产精品嫩草影院| 欧美在线视频a| 久久露脸国产精品| 国产欧美精品xxxx另类| 亚洲午夜性刺激影院| 中文久久精品| 国产精品黄色在线观看| 在线亚洲欧美专区二区| 亚洲在线免费观看| 国产精品久久9| 亚洲午夜91| 久久成人一区| 激情五月***国产精品| 久久视频在线视频| 欧美大色视频| 99国产一区| 欧美体内she精视频在线观看| 日韩视频在线观看一区二区| 亚洲一区不卡| 国产精品日韩精品| 亚洲欧美日韩久久精品| 久久精品国产亚洲aⅴ| 在线看日韩欧美| 欧美激情一区二区三区不卡| 亚洲三级观看| 欧美一区亚洲| 在线免费观看日韩欧美| 欧美韩国一区| 亚洲无人区一区| 美国十次了思思久久精品导航| 亚洲福利精品| 欧美日韩在线观看一区二区| 亚洲一区国产精品| 老司机免费视频一区二区三区| 久久综合九九| 午夜免费日韩视频| 黄色一区二区在线| 欧美v亚洲v综合ⅴ国产v| 亚洲精品一区二区三| 亚洲欧美美女| 影音先锋中文字幕一区| 欧美日产国产成人免费图片| 午夜精品一区二区三区电影天堂 | 99av国产精品欲麻豆| 午夜一区不卡| 亚洲第一成人在线| 欧美体内she精视频| 久久综合给合久久狠狠色 | 久久久999精品| 一本色道久久综合亚洲精品小说 | 午夜精品视频网站| …久久精品99久久香蕉国产 | 亚洲一区二区三区四区中文| 久久免费精品日本久久中文字幕| 亚洲免费观看高清完整版在线观看| 国产精品区一区| 欧美国产综合一区二区| 欧美在线欧美在线| 亚洲视频精选| 亚洲三级视频| 欧美成人免费视频| 久久www免费人成看片高清| 99视频在线观看一区三区| 影音先锋欧美精品| 国产一区二区三区在线观看视频| 欧美日韩四区| 欧美成人午夜激情在线| 久久成人国产精品| 亚洲欧美日韩在线高清直播| 亚洲国产专区| 亚洲第一网站| 亚洲第一主播视频| 欧美大片第1页| 欧美成人午夜激情在线| 玖玖玖国产精品|