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

来源:互联网 发布:淘宝售前客服兼职 编辑:程序博客网 时间:2024/05/22 02:47

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:       /** Constructor without params is required */        Point(int px = 0, int py = 0) : x_(px), y_(py) {}        Point(Point* p) : x_(p->x_), y_(p->y_) {}         int x_;        int y_;        /** Example call to function without params */       int GetManhattanLength()  { return std::abs(x_) - std::abs(y_); }        /** this will create a JS object, with JS destructor */        Point* Copy() { return new Point(); }        /** Example call to function with params */        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:      /** Constructor without params is required */         /** Example of object property, it can be manipulate directly */      Point start;         /** this will create a JS object, without destructor and a reference to this        *  end instance        *       */      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      ...
如果借助宏,就较简单:

   // 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       0       > x.x = 10       10       > line.getEnd().x       0       > 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/


转自:http://kb.cnblogs.com/a/1670016/