• 在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:
    /** 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
    >_

      

    官方网站:

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

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

  • 相关阅读:
    Vue 下拉刷新及无限加载组件
    VUE常用问题hack修改
    CSS滤镜让图片模糊(毛玻璃效果)实例页面
    滑动删除
    拖动选择单元格并合并方法
    Windows7上开启ftp服务器功能
    js 向上滚屏
    理解Clip Path
    图标制作
    transition实现图片轮播
  • 原文地址:https://www.cnblogs.com/Tue/p/1670016.html
Copyright © 2020-2023  润新知