2013-04-13 10 views
9

Ich schreibe node.js Bindings und ich möchte JSON-String von v8 :: Object-Instanzen generieren. Ich möchte es in C++ machen. Da node.js bereits JSON.stringify hat, möchte ich es verwenden. Aber ich weiß nicht, wie man aus dem C++ Code darauf zugreifen kann.Zugriff auf JSON.stringify von node.js C++ - Bindungen

Antwort

5

Sie müssen einen Verweis auf das globale Objekt greifen und dann die stringify-Methode abrufen;

Local<Object> obj = ... // Thing to stringify 

// Get the global object. 
// Same as using 'global' in Node 
Local<Object> global = Context::GetCurrent()->Global(); 

// Get JSON 
// Same as using 'global.JSON' 
Local<Object> JSON = Local<Object>::Cast(
    global->Get(String::New("JSON"))); 

// Get stringify 
// Same as using 'global.JSON.stringify' 
Local<Function> stringify = Local<Function>::Cast(
    JSON->Get(String::New("stringify"))); 

// Stringify the object 
// Same as using 'global.JSON.stringify.apply(global.JSON, [ obj ]) 
Local<Value> args[] = { obj }; 
Local<String> result = Local<String>::Cast(stringify->Call(JSON, 1, args)); 
+0

Einige Dinge haben sich offenbar in der V8-API geändert: 1. Es gibt keine 'GetCurrent' ist und in der Regel erhalten Sie die globalen aus dem Isolat mit' Isolat-> getCurrentContext() -> Global() '. 2. Es gibt kein 'String :: New()' und normalerweise wollen Sie 'String :: NewFromUTF8()'. Glauben Sie nicht, dass dies eine andere Antwort rechtfertigt, aber es wäre ein Anruf, wenn Sie Ihren aktualisieren. – Stav

1

Einige der Knoten-APIs haben sich seit der Veröffentlichung des OP geändert. Unter der Annahme einer node.js-Version 7.7.1 wird der Code in etwas wie folgt umgewandelt:

std::string ToJson(v8::Local<v8::Value> obj) 
{ 
    if (obj.IsEmpty()) 
     return std::string(); 

    v8::Isolate* isolate = v8::Isolate::GetCurrent(); 
    v8::HandleScope scope(isolate); 

    v8::Local<v8::Object> JSON = isolate->GetCurrentContext()-> 
     Global()->Get(v8::String::NewFromUtf8(isolate, "JSON"))->ToObject(); 
    v8::Local<v8::Function> stringify = JSON->Get(
     v8::String::NewFromUtf8(isolate, "stringify")).As<v8::Function>(); 

    v8::Local<v8::Value> args[] = { obj }; 
    // to "pretty print" use the arguments below instead... 
    //v8::Local<v8::Value> args[] = { obj, v8::Null(isolate), v8::Integer::New(isolate, 2) }; 

    v8::Local<v8::Value> const result = stringify->Call(JSON, 
     std::size(args), args); 
    v8::String::Utf8Value const json(result); 

    return std::string(*json); 
} 

Grundsätzlich wird der Code das JSON Objekt von dem Motor erhält einen Verweis auf die Funktion stringify dieses Objekts, und dann ruft es. Der Code ist gleichbedeutend mit dem Javascript;

var j = JSON.stringify(obj); 

Weitere v8 Alternativen umfassen die JSON Klasse.

auto str = v8::JSON::Stringify(v8::Isolate::GetCurrent()->GetCurrentContext(), obj).ToLocalChecked(); 
v8::String::Utf8Value json{ str }; 
return std::string(*json);