天天看點

在C++中嵌入JavaScript——Google V8 JavaScript Engine使用體驗

Google V8 Script Engine 使用體驗

Google V8 JavaScript Engine是google為 Chrome's浏覽器開發的腳本引擎,現在可以使用V8 JavaScript Engine在C++程式中建立自己的腳本環境。

1.準備工作

1). 安裝一個SVN用戶端 http://tortoisesvn.net/downloads,google v8 在官方網站僅以此方式釋出;

2).下載下傳一個python:位址http://sourceforge.net/projects/pywin32/files/,官方網站2009年10月15日被牆了

2.checkout并準備環境

      0)設定目錄:

+third_party

+python_24         Python位置(拷貝或安裝到均可)

       +V8 V8 check out 位置

1)安裝python

---------------------------------------begin-------------------------------------------------

     說明:

由于v8.project在配置時,使用如下指令進行處理:

.\d8js2c.cmd ..\..\src "$(IntDir)\DerivedSources"

其中: d8js2c.cmd(line4): set PYTHON="..\..\..\third_party\python_24\python.exe"

顯然python和相關庫應該位于:..\..\..\third_party\python_24\

---------------------------------------end---------------------------------------------------

2)下載下傳 Google V8 Script Engine下載下傳,

      SVN位址: http://code.google.com/p/v8/source/checkout

3)編譯

V8\tools\visual_studio\v8.sln

這樣就可以編譯了,如果編譯失敗,那可能就是python沒有配置好。

3. JS 嵌入C++示例代碼

一個Hello world!

#include " http://www.cnblogs.com/include/v8.h "

#pragma comment(lib,"../visual_studio/Release/lib/v8.lib")

#pragma comment(lib,"../visual_studio/Release/lib/v8_base.lib")

using namespace v8;

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

// Create a stack-allocated handle scope.

HandleScope handle_scope;

// Create a new context.

Persistent < Context > context = Context::New();

// Enter the created context for compiling and

// running the hello world script.

Context::Scope context_scope(context);

// Create a string containing the JavaScript source code.

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

// Compile the source code.

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

// Run the script to get the result.

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

// Dispose the persistent context.

context.Dispose();

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

String::AsciiValue ascii(result);

printf( " %s\n " , * ascii);

return 0 ;

}

更多示例代碼參考:V8\test\cctest\*.cc

4.支援C++類

CProxyV8提供便利的方式将C++類的屬性和方法導出到JavaScript環境中。支援generic Functors,不需要為每個屬性和方法設定回調函數。

class Point

{

public :

Point( int px = 0 , int py = 0 ) : x_(px), y_(py) {}

Point(Point * p) : x_(p -> x_), y_(p -> y_) {}

int x_;

int y_;

int GetManhattanLength() { return std::abs(x_) - std::abs(y_); }

Point * Copy() { return new Point(); }

v8::Handle < v8::Value > Translate( const v8::Arguments & args)

{

// throw if we didn't get 2 args

if (args.Length() != 2 )

return ThrowException(v8::String::New( " Expected 2 arguments " ));

x_ += args[ 0 ] -> Int32Value();

y_ += args[ 1 ] -> Int32Value();

return v8::True();

};

};

class Line

{

public :

Point start;

Point & GetEnd() { return end; }

private :

Point end;

};

int main( int argc, char * argv[])

{

v8::V8::SetFlagsFromCommandLine( & argc, argv, true );

v8::HandleScope handle_scope;

// Create a template for the global object.

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

ProxyClass < Foo >* pPoint = ProxyClass < Foo > ::instance(); // Get the proxy class for Point

pPoint -> Expose( & Point::x_, " x " , true , true ); // expose x_ for read/write

pPoint -> Expose( & Point::y_, " y " , true , true ); // expose y_ for read/write

pPoint -> Expose( & Point::Copy, " copy " );

pPoint -> Expose( & Point::GetManhattanLength, " getManhattanLength " );

pPoint -> Expose( & Point::Translate, " translate " );

ProxyClass < Line >* pLine = ProxyClass < Line > ::instance(); // Get the proxy class for Line

pPoint -> Expose( & Line::start, " start " , true , true ); // expose object start for read/write

pPoint -> Expose( & Line::GetEnd, " getEnd " );

global -> Set(v8::String::New( " Point " ), pPoint -> GetFunctionTemplate()); // add Point to JS

global -> Set(v8::String::New( " Line " ), pLine -> GetFunctionTemplate()); // add Line to JS

...

如果借助宏,就較簡單:

int main( int argc, char * argv[])

{

v8::V8::SetFlagsFromCommandLine( & argc, argv, true );

v8::HandleScope handle_scope;

// Create a template for the global object.

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

CPROXYV8_PROPERTY_ID(Point,x_,x, true , true );

CPROXYV8_PROPERTY_ID(Point,y_,y, true , true );

CPROXYV8_METHOD_ID(Point,Copy, copy);

CPROXYV8_METHOD_ID(Point,GetManhattanLength, getManhattanLength);

CPROXYV8_METHOD(Point,Translate);

CPROXYV8_PROPERTY(Line,start, true , true );

CPROXYV8_METHOD_ID(Line,GetEnd,getEnd);

global -> Set(v8::String::New( " Point " ), CPROXYV8_CLASS(Point) -> GetFunctionTemplate()); // add Point to JS

global -> Set(v8::String::New( " Line " ), CPROXYV8_CLASS(Line) -> GetFunctionTemplate()); // add Line to JS

在Shell中使用這些類:

V8 version 0.4 . 3.1

> x = new Point()

[object Point]

> line = new Line()

[object Line]

> x.x

> x.x = 10

10

> line.getEnd().x

> line.getEnd().x = 10

10

> line.getEnd().x

10

> end = line.getEnd();

[object Point]

> end.x

10

> end.Translate( 10 , 10 )

true

> end.x

20

> line.getEnd().x

20

> x.x

10

> _

官方網站:

http://code.google.com/p/v8/

http://code.google.com/p/cproxyv8/

轉載于:https://www.cnblogs.com/Tue/archive/2010/02/21/1670016.html