1

変更された引数を使用して C++ 側から JSON.stringify メソッドを呼び出したいのですが、頭に浮かんだ解決策は、すべてのフレームが "??" である奇妙なセグメンテーション違反になります。

私は次のことをしたいと考えています: api::Console はデバッグ目的のカスタム コンソール実装であり、したがって api::Console::handleLog や api::Console::handleDebug のような静的メソッドがあります。

コンソールの ObjectTemplate に正しく渡される handleDebug の場合、次は機能しません。v8gl::context は現在の実行コンテキストであり、他の API 実装で正しく使用できます。

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 のバックトレースはどういうわけか奇妙で、その理由がわかりません:

(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::Function の Call() メソッドで使用するために、ローカル値 "v8::Arguments& args" から "v8::Handle<v8::Value>*" に正しくキャストするにはどうすればよいですか?

args[a] をループで直接使用したい場合、v8::Function::Call の異なるシグネチャに対してコンパイラ エラーがスローされますが、これは args がローカル値であるため正しいものです。v8::Function::Call の署名は次のとおりです。

v8::Local<v8::Value> v8::Function::Call(v8::Handle<v8::Object>, int, v8::Handle <v8::Value>*)

// 編集: passargs[false index] を更新

4

1 に答える 1

2

そこにエラーがあります:

    v8::Handle<v8::Value> passargs[1];

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

したがって、配列の範囲外の要素にアクセスしようとします。

ところで: v8::Local<>から継承されているので、に変換するためv8::Handle<>の魔法は必要ありません。LocalHandle

編集: v8の機能のほとんどは、コンテキストスコープを作成する必要があるだけでなく、作成する必要があるようですv8::HandleScopev8::Context::Scope有効なコンテキストフォームを取得できますargs

Local<Object> self = args.Holder();
Persistent<Context> context(self->CreationContext());

次に、ハンドルスコープとコンテキストスコープを作成します。

Context::Scope work_in_context_scope(context);
HandleScope work_in_this_function_scope;

それならあなたは仕事をしますか。

于 2012-07-31T10:26:15.493 に答える