首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用自定义修改的V8::参数调用V8::函数?

如何使用自定义修改的V8::参数调用V8::函数?
EN

Stack Overflow用户
提问于 2012-07-31 10:19:19
回答 1查看 2.1K关注 0票数 1

我想用修改过的参数从C++端调用C++方法,但是在我脑海中出现的任何解决方案都会导致一个奇怪的分段错误,所有帧都位于"??“。

我想做以下工作: api::Console是一个用于调试的自定义控制台实现,因此具有诸如api:: console ::handleLog或api::Console::handleDebug之类的静态方法。

对于正确传递给控制台的handleDebug的ObjectTemplate,以下内容不起作用,v8gl::context是当前的执行上下文,在其他ObjectTemplate实现中正确可用:

代码语言:javascript
复制
v8::Handle<v8::Value> Console::handleDebug(const v8::Arguments& args) {

    if (args.Length() < 1) {
        return v8::Undefined();
    }

    v8::HandleScope scope;

    v8::Handle<v8::Object> global = v8gl::context->Global();
    v8::Handle<v8::Object> JSON = global->Get(v8::String::New("JSON"))->ToObject();
    v8::Handle<v8::Function> JSON_stringify = v8::Handle<v8::Function>::Cast(JSON->Get(v8::String::New("stringify")));


    for (signed a = 0; a < args.Length(); a++) {

        for (int m = 0; m < consoleMargin; m++) {
            fprintf(stdout, "\t");
        }

        v8::Handle<v8::Value> passargs[1];
        // alternative try was:
        // passargs[0] = v8::String::New("{foo:'bar'}");
        passargs[0] = v8::String::New(*v8::String::Utf8Value(args[a]->ToString()));


        v8::String::Utf8Value value(JSON_stringify->Call(JSON, 1, passargs));
        char* message = *value;

        fprintf(stdout, "%s\n", message);

    }


    return scope.Close(v8::Undefined());

}

gdb中的反向跟踪有点奇怪,我不知道为什么:

代码语言:javascript
复制
(gdb) backtrace
#0  0x00000000004a0880 in v8::Context::Global() ()
#1  0x00000000004128ea in api::Console::handleDebug(v8::Arguments const&) ()
#2  0x00000000004b9eab in v8::internal::Builtin_HandleApiCall(v8::internal::(anonymous namespace)::BuiltinArguments<(v8::internal::BuiltinExtraArguments)1>, v8::internal::Isolate*) ()
#3  0x000004cd67f0618e in ?? ()
#4  0x000004cd67f12998 in ?? ()
#5  0x000004cd67f060e1 in ?? ()
# (... etc ...)

因此,我的问题如下:

如何正确地将本地值“V8::args”转换为"v8::Handle*“,以便与V8::的Call()方法一起使用

如果我想直接在循环中使用argsa,则会为v8::Function::Call的不同签名抛出编译器错误,这是正确的,因为args是一个本地值。v8::Function::Call的签名如下:

v8::Local V8:函数::Call(v8::Handle,int,V8:Handle *)

//编辑:更新passargsfalse索引

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-31 10:26:15

您在那里有错误:

代码语言:javascript
复制
    v8::Handle<v8::Value> passargs[1];

    passargs[1/* SHOULD BE 0!!!*/] = 
         v8::String::New(*v8::String::Utf8Value(args[a]->ToString()));

因此,您尝试访问数组边界之外的元素。

BTW: v8::Local<>是从v8::Handle<>继承的,所以您不需要任何魔法就可以将Local转换为Handle

编辑:大多数v8特性不仅需要v8::HandleScope,而且v8::Context::Scope似乎也需要创建上下文范围。您可以从args中获得有效的上下文

代码语言:javascript
复制
Local<Object> self = args.Holder();
Persistent<Context> context(self->CreationContext());

然后创建句柄作用域和上下文作用域:

代码语言:javascript
复制
Context::Scope work_in_context_scope(context);
HandleScope work_in_this_function_scope;

那就做好你的工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11737933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档