如何返回一个新的V8 javascript" class"来自C ++中的实例?

时间:2016-12-18 18:33:02

标签: javascript c++ v8 embedded-v8

当使用V8作为脚本引擎时,我向Javascript公开了一个名为construct_with_ec6_syntax的C ++函数。调用此函数时,应该只返回some_ec6_class

的实例

这个C ++函数基本上应该执行以下等效的Javascript:

return new some_ec6_class(111, 222);

此类将在Javascript中定义如下 with EC6语法:

class some_ec6_class
{
    constructor(x, y) {
        this.result = x + y;
    }
}

我的目标是在Javascript中运行以下内容...

var the_instance = construct_with_ec6_syntax(111, 222);
the_instance.result ; // .. and get 333 here.

我目前对C ++函数的实现是这样的:

void construct_with_ec6_syntax(const FunctionCallbackInfo<Value>& args) {
    Handle<Object> global = args.GetIsolate()->GetCurrentContext()->Global();
    std::string newvecfunc = "some_ec6_class";
    Handle<Value> value = global->Get(String::NewFromUtf8(args.GetIsolate(), newvecfunc.c_str(), String::kNormalString, newvecfunc.length()));
    Local<Value> result;
    if (value->IsFunction()) {
        Handle<Function> func = Handle<Function>::Cast(value);
        Handle<Value> args2[2];
        args2[0] = Number::New(args.GetIsolate(), 111);
        args2[1] = Number::New(args.GetIsolate(), 222);
        result = func->CallAsConstructor(args.GetIsolate()->GetCurrentContext(), 2, args2).ToLocalChecked();
    }   
    args.GetReturnValue().Set(result);
}   

从Javascript运行此函数使其返回undefined!而不是我期望的对象。正如xaxxon向我指出的那样,因为value->IsFunction()返回false,但value->IsUndefined()返回true。如果我使用 EC6语法定义了类,则上面的函数返回一个实例..

function some_non_ec6_class(x, y) // this guy would work with the above function
{
    this.result = x + y;
}

所以我有点困惑!我是否需要更具体,比如首先从对象获取constructor函数,然后调用CallAsConstructor

任何提示都表示赞赏!

(这个问题看起来类似于 Calling a v8 javascript function from c++ with an argument但不同。)

我从2016年10月22日起使用V8结帐。 完整的测试用例:

https://gist.github.com/rayburgemeestre/c0abd528f6f67edbfe686d484c45ddbb

次要更新:

正如您在评论中看到的那样,我还提出了一个更具体的测试案例,其中包括&#34;提取&#34;来自上下文的类:https://gist.github.com/rayburgemeestre/df6193d532c7b7908fe27c89799bfa3a

我也发布到v8-users邮件列表:https://groups.google.com/forum/#!topic/v8-users/Hj2j4rJMwBw

1 个答案:

答案 0 :(得分:2)

class是一种在javascript中创建变量的方法,类似于let。使用class创建的变量是块作用域,不会创建全局属性(同样,类似于let)。因此,它在context.global中不可用,就像函数一样:

http://exploringjs.com/es6/ch_variables.html

function    Complete    Block   Yes

class       No          Block   No

您需要显式创建一个全局变量才能使代码正常工作:

some_es6_class = class{}; 

或使用传统的es6&#39;创建它后,将类对象显式传递给c ++函数。语法:

class some_es6_class{};
some_native_function(some_es6_class);

编辑:我已经做了一些挖掘工作,我相信上下文对象有一个LexicalEnvironment,它在script之间共享,但与全局对象不同。查找名称时,它会遍历LexicalEnvironments的父层次结构以查找名称。这些词汇环境不是通过API公开的(实际上可能不存在 - 它们是JS规范用来定义行为的构造,而不是实现的必需部分)