2012-01-24 28 views
7

Tôi đang tạo bảng điều khiển dựa trên vỏ v8, tôi lấy mã mẫu có came v8 và nó hoạt động rất tốt, nhưng tôi đang cố chuyển đổi đối tượng v8 :: thành phiên bản chuỗi của nó (json) nhưng didnt findout một cách để làm điều đó.Sử dụng stringify từ vỏ v8

Dưới đây là mẫu mã của tôi bên trong shell.cc:



    v8::Handle test(const v8::Arguments& args) { 
     v8::HandleScope handle_scope; 
     const char* json; 
     v8::String::Utf8Value strJson(args[0]); 
     printf(ToCString(json)); 
     if (args[0]->IsObject()) { 
      printf("it's an object\n"); 
     } 
     return v8::String::New(""); 
    } 

Tại vỏ Tôi tạo ra một tập tin test.js với điều này:



    var a = { name: 'John' }; 
    test(a); 

và tôi có được điều này sau khi thực hiện js trong vòng vỏ console:



    [object Object] 
    It's an object 

những gì tôi muốn là:



    { "name": "John" } 

nếu tôi thay đổi mã js để:



    var a = { name: 'John'} 
    test(JSON.stringify(a)); 

nó hoạt động rất tốt, nhưng tôi không muốn người dùng cần phải biết làm thế nào để phân tích một biến javascript vào json, và tôi không muốn để kiểm tra mọi đầu vào đơn lẻ tại đối tượng và phân tích cú pháp theo cách thủ công.

Có cách nào để thực hiện cùng một lệnh trong mã shell.cc trong C không? cái gì đó như:



    v8::Handle<v8::String> temp = JSON.parse(arg[0]); 

cập nhật: Đây là cách tôi xử lý này, nhưng tôi muốn có một cách sạch hơn để làm điều tương tự:



    const char* toJson(const v8::Local<v8::Object>& obj) { 
     std::stringstream ss; 
     ss << "{"; 
     v8::Local<v8::Array> propertyNames = obj->GetPropertyNames(); 

     for (int x = 0; x < propertyNames->Length(); x++) { 
      if (x != 0) { 
      ss << ", "; 
      } 
      v8::String::Utf8Value name(propertyNames->Get(x)); 
      ss << "\"" << ToCString(name) << "\":"; 
      v8::Local<v8::Value> val = obj->GetInternalField(x); 
      if (val->IsObject()) { 
       ss << toJson(val->ToObject()); 
      } else { 
       ss << "\"" << ToCString(v8::String::Utf8Value(val)) << "\""; 
      } 
     } 

     ss << "}"; 

     const char* result = ss.str().c_str(); 
     return result; 
    } 

    v8::Handle test(const v8::Arguments& args) { 
     v8::HandleScope handle_scope; 
     const char* json; 
     v8::String::Utf8Value strJson(args[0]); 
     if (args[0]->IsObject()) { 
      char* json = toJson(args[0]); 
      // ... 
      // Some operations with the json 
      // ... 
     } 
     return v8::String::New(""); 
    } 

Trả lời

10

tôi thấy cách này làm ngược lại (JSON để đối tượng v8), sử dụng các v8 được xây dựng trong chức năng JSON.parse. http://www.mail-archive.com/[email protected]/msg04430.html

Điều chỉnh này để sử dụng JSON.stringify thay vào đó sẽ trông giống như này (chưa được kiểm tra):

Handle<String> toJson(Handle<Value> object) 
{ 
    HandleScope scope; 

    Handle<Context> context = Context::GetCurrent(); 
    Handle<Object> global = context->Global(); 

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

    return scope.Close(JSON_stringify->Call(JSON, 1, object)); 
} 
0

tôi muốn tránh sử dụng các phương pháp V8 bây giờ bị phản đối để thực hiện riêng của tôi về v8::Value -to- string chuyển đổi, vì vậy tôi đặt cùng chức năng này, lấy cảm hứng từ câu trả lời của Michael. Nhược điểm là nó rất tiết lộ:

bool MakeStringValue(const string& str, v8::Isolate* isolate, 
        v8::Handle<v8::Value>* out_value) { 
    const v8::MaybeLocal<v8::String> maybe_string = v8::String::NewFromUtf8(
     isolate, str.c_str(), v8::NewStringType::kNormal, str.size()); 
    v8::Handle<v8::String> value; 
    if (!maybe_string.ToLocal(&value)) { 
    return false; 
    } 
    *out_value = static_cast<v8::Handle<v8::Value>>(value); 
    return true; 
} 

bool ConvertValueToString(v8::Handle<v8::Value> value, v8::Isolate* isolate, 
          v8::Local<v8::Context> context, 
          string* value_string) { 
    v8::Local<v8::Object> global = context->Global(); 

    v8::Handle<v8::Value> json_string_value; 
    v8::Handle<v8::Value> stringify_string_value; 
    if (!MakeStringValue("JSON", isolate, &json_string_value) || 
     !MakeStringValue("stringify", isolate, &stringify_string_value)) { 
    return false; 
    } 
    const v8::MaybeLocal<v8::Value> maybe_json_value = 
     global->Get(context, json_string_value); 
    v8::Handle<v8::Value> json_value; 
    if (!maybe_json_value.ToLocal(&json_value)) { 
    return false; 
    } 

    v8::MaybeLocal<v8::Object> maybe_json_object = json_value->ToObject(context); 
    v8::Handle<v8::Object> json_object; 
    if (!maybe_json_object.ToLocal(&json_object)) { 
    return false; 
    } 

    const v8::MaybeLocal<v8::Value> maybe_stringify_value = 
     json_object->Get(context, stringify_string_value); 
    v8::Handle<v8::Value> stringify_value; 
    if (!maybe_stringify_value.ToLocal(&stringify_value)) { 
    return false; 
    } 

    v8::Function* stringify_function = v8::Function::Cast(*stringify_value); 

    v8::TryCatch try_catch(isolate); 
    const v8::MaybeLocal<v8::Value> maybe_result = 
     stringify_function->Call(context, json_object, 1, &value); 
    v8::Local<v8::Value> result; 
    if (try_catch.HasCaught() || !maybe_result.ToLocal(&result) || 
     result.IsEmpty() || result->IsNullOrUndefined() || !result->IsString()) { 
    return false; 
    } 

    v8::Local<v8::String> result_string; 
    if (!result->ToString(context).ToLocal(&result_string)) { 
    return false; 
    } 
    v8::String::Utf8Value utf8_value(result_string); 
    // operator* returns a const char*. 
    if (*utf8_value == nullptr) { 
    return false; 
    } 
    value_string->assign(*utf8_value, utf8_value.length()); 
    return true; 
} 
Các vấn đề liên quan