C ++范围和Google V8脚本上下文

时间:2015-10-16 11:02:43

标签: c++ scope v8 embedded-v8 libv8

我有以下几乎用c ++编写的代码:

<!DOCTYPE html>
<html>

<head>
<title>CSS Portal - Layout</title>
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<STYLE>
/*    Generated by http://www.cssportal.com    */

@import url("reset.css");

body {
    font-family: Verdana, Arial, Helvetica, sans-serif;
    font-size: 13px;
    color:#333
}

p {
    padding: 10px;
}

#wrapper {
    width: 100%;
    min-width: 600px;
    max-width: 1000px;
    margin: 0 auto;
}

#headerwrap {
    width: 100%;
    float: left;
    margin: 0 auto;
}

#header {
    height: 75px;
    background: #FF6633;
    border-radius: 10px;
    border: 1px solid #eb521f;
    margin: 5px;
}

#navigationwrap {
    width: 100%;
    float: left;
    margin: 0 auto;
}

#navigation {
    height: 40px;
    background: #FFCC33;
    border-radius: 10px;
    border: 1px solid #ebb81f;
    margin: 5px;
}

#contentliquid {
    float: left;
    width: 100%;
}

#contentwrap {
    margin-left: 150px;
    margin-right: 150px;
    float: left;
}

#content {
    background: #FF724F;
    border-radius: 10px;
    border: 1px solid #eb5e3b;
    margin: 5px;
}

#leftcolumnwrap {
    width: 150px;
    margin-left:-100%;
    float: left;
}

#leftcolumn {
    background: #33CCFF;
    border-radius: 10px;
    border: 1px solid #1fb8eb;
    margin: 5px;
}

#rightcolumnwrap {
    width: 150px;
    margin-left: -150px;
    float: left;
}

#rightcolumn {
    background: #CC33FF;
    border-radius: 10px;
    border: 1px solid #b81feb;
    margin: 5px;
}

#footerwrap {
    width: 100%;
    float: left;
    margin: 0 auto;
    clear: both;
}

#footer {
    height: 40px;
    background: #33FF66;
    border-radius: 10px;
    border: 1px solid #1feb52;
    margin: 5px;
}
</STYLE>
</head>
<body>
    <div id="wrapper">
        <div id="headerwrap">
        <div id="header">

            <?PHP include 'header_page.php'; ?>
        </div>
        </div>
        <div id="navigationwrap">
        <div id="navigation">


        </div>
        </div>
        <div id="contentliquid"><div id="contentwrap">
        <div id="content">

            <?PHP include 'main.php'; ?>

        </div>
        </div></div>
        <div id="leftcolumnwrap">
        <div id="leftcolumn">

            <?PHP include 'left.php'; ?>
        </div>
        </div>
        <div id="rightcolumnwrap">
        <div id="rightcolumn">

            <?PHP include 'right.php'; ?>
        </div>
        </div>
        <div id="footerwrap">
        <div id="footer">

            <?PHP include 'footer.php'; ?>
        </div>
        </div>
    </div>
</body>
</html>

我有函数setupJs()设置v8环境,callJs应该被多次调用(工作时,javascript脚本每次增加一个var)。

如果我把

[..]

Handle<Object> jsGlobal;
Handle<Function> jsUpdateFunc;

void setupJs () {
    V8::Initialize();
    Isolate* isolate = v8::Isolate::New();
    Isolate::Scope isolate_scope(isolate);
    HandleScope handle_scope(isolate);
    Local<Context> context = Context::New(isolate);
    Context::Scope context_scope(context);
    Local<String> source = String::NewFromUtf8(isolate, "var a = 0; function test() { a++; return a.toString(); }");
    Local<Script> script = Script::Compile(source);
    script->Run();

    jsGlobal = context->Global();
    Handle<Value> value = jsGlobal->Get(String::NewFromUtf8(isolate, "test"));
    jsUpdateFunc = Handle<Function>::Cast(value);
}

void callJs() {
    Handle<Value> args[0];
    Handle<Value> js_result = jsUpdateFunc->Call(jsGlobal, 0, args);
    js_result->ToString();

    String::Utf8Value utf8(js_result);
    printf("%s\n", *utf8);
}

[..]
在setupJs中,我可以看到如何调用函数s和“1”。但是,如果我将函数调用与稍后调用的函数调用一起使用,我在行Handle<Value> args[0]; Handle<Value> js_result = jsUpdateFunc->Call(jsGlobal, 0, args); js_result->ToString(); String::Utf8Value utf8(js_result); printf("%s\n", *utf8); 处有一个Segfault

我已经检查过,jsUpdateFunc和jsGlobal都是非空指针

1 个答案:

答案 0 :(得分:6)

您需要为jsGlobaljsUpdateFunc使用持久句柄。正常(本地)句柄在其封闭的v8::HandleScope被销毁时变为无效。

您还需要v8::Isolate指针的全局变量,以及v8::Context的持久句柄的另一个变量。

要稍后调用脚本函数,您需要:

  1. 锁定隔离区(您确实应该在setupJs中执行此操作;请参阅v8::Locker
  2. 输入隔离区(请参阅v8::Isolate::Scope)。
  3. 建立句柄范围(参见v8::HandleScope)。
  4. 为上下文创建本地句柄。
  5. 输入上下文(请参阅v8::Context::Scope)。
  6. jsGlobaljsUpdateFunc创建本地句柄。
  7. 按上述方式调用脚本函数。
  8. 在V8头文件中查找v8::Persistent及相关模板。