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

原文:http://kb.cnblogs.com/a/1670016

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!

 // 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 
     ...
如果借助宏,就较简单:

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 
      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 
      >_


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值