[英]How to parse JSON in an embedded v8?
我试图在我的嵌入式V8应用程序中解析JS,我总是得到一个SIGSEGV。 我不确定发生了什么。
我解析json的代码,
v8::Handle<v8::Value> FromJSONString(
v8::Handle<v8::Value> json_string) {
v8::HandleScope scope;
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
v8::Handle<v8::Object> global = context->Global();
v8::Handle<v8::Value> JSON_value = global->Get(v8::String::New("JSON"));
if (!IsObject(JSON_value)) {
return scope.Close(v8::Undefined());
}
v8::Handle<v8::Object> JSON = JSON_value->ToObject();
v8::Handle<v8::Value> JSON_parse_value = JSON->Get(v8::String::New("parse"));
if (JSON_parse_value.IsEmpty() || JSON_parse_value->IsNull() ||
JSON_parse_value->IsUndefined() ||!JSON_parse_value->IsFunction()) {
return scope.Close(v8::Undefined());
}
v8::Handle<v8::Function> JSON_parse =
v8::Handle<v8::Function>::Cast(JSON_parse_value);
return scope.Close(JSON_parse->Call(JSON, 1, &json_string));
}
崩溃的具体网站=>
bool extractSource(std::string* source, std::string& body) {
v8::HandleScope scope; // this is needed and clears the memory
if (body.empty()) {
return false;
}
v8::Handle<v8::Value> value = v8_server_utils::FromJSONString(body);
if (value->IsEmpty()) { // CRASHES HERE.
return false;
}
if (value->IsNull()) {
return false;
}
if (value->IsUndefined()) {
return false;
}
if (!value->IsObject()) {
return false;
}
auto object = value->ToObject();
auto source_key = v8::String::New("source");
if (object.IsEmpty() || object->IsNull() || object->IsUndefined() ||
!object->Has(source_key)) {
return false;
}
auto source_obj = object->Get(source_key);
*source = v8_server_utils::JSStringToCString(source_obj->ToString());
return true;
}
您可以使用通过API公开的JSON Parse函数:
v8::Local<v8::String> str; // some string
v8::Local<v8::Value> result = v8::JSON::Parse(str);
较新版本的V8提供了EscapableHandleScope
您需要使用它来从函数返回句柄:
v8::EscapableHandleScope scope(isolate);
return scope.Escape(value);
这个
if (value->IsEmpty()) { // CRASHES HERE.
应该是
if (value.IsEmpty())
希望这可以帮助。
如果您使用的是较旧的V8版本,例如v3.14,则以下代码应该可以正常工作:
v8::Handle<v8::Value> FromJsonString (v8::Handle<v8::Value> jsonString) {
v8::HandleScope scope;
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
v8::Handle<v8::Object> global = context->Global();
// find JSON object in global scope
v8::Handle<v8::Value> jsonValue = global->Get(v8::String::New("JSON"));
if (! jsonValue->IsObject()) {
return scope.Close(v8::Undefined());
}
v8::Handle<v8::Object> json = jsonValue->ToObject();
// find "parse" attribute
v8::Handle<v8::Value> parse = json->Get(v8::String::New("parse"));
if (parse.IsEmpty() ||
! parse->IsFunction()) {
return scope.Close(v8::Undefined());
}
// cast into a function
v8::Handle<v8::Function> parseFunction = v8::Handle<v8::Function>::Cast(parse);
// and call it
return scope.Close(parseFunction->Call(json, 1, &jsonString));
}
static bool ExtractSource (std::string& source, std::string const& body) {
v8::HandleScope scope;
// convert whole body from cstring to V8 string
v8::Handle<v8::String> bodyString = v8::String::New(body.c_str(), body.size());
// call JSON.parse() on the body
v8::Handle<v8::Value> value = FromJsonString(bodyString);
// check if result is valid
if (value.IsEmpty() ||
value->IsNull() ||
value->IsUndefined() ||
! value->IsObject()) {
return false;
}
auto object = value->ToObject();
// extract "source" attribute from result
auto sourceKey = v8::String::New("source");
if (object.IsEmpty() ||
object->IsNull() ||
object->IsUndefined() ||
! object->Has(sourceKey)) {
return false;
}
auto sourceValue = object->Get(sourceKey);
if (! sourceValue->IsString()) {
return false;
}
// convert the v8 string value into a cstring
v8::String::Utf8Value sourceString(sourceValue->ToString());
if (*sourceString == nullptr) {
return false;
}
source.assign(*sourceString, sourceString.length());
return true;
}
int main () {
// test data
std::string body = "{ \"body\": \"test\", \"source\": \"some string value\" }";
// result
std::string source;
// call function and dump result
std::cout << "is valid: " << ExtractSource(source, body) << std::endl;
std::cout << "value of source: '" << source << "'" << std::endl;
}
如果您正在编写本机节点模块并使用NAN以便在所有主要版本的Node.js中支持它,那么我建议您尝试使用native-json npm包。
该包公开了以下方法:
static Nan::MaybeLocal<v8::Value> Native::JSON::Parse(v8::Local<v8::String> jsonString);
static Nan::MaybeLocal<v8::String> Native::JSON::Stringify(v8::Local<v8::Object> jsonObject, v8::Local<v8::String> gap = v8::Local<v8::String>())
至于NAN支持的节点版本中v8::JSON
的更改:
v8::JSON::Parse
最先可用的节点版本0.12.x -它不是在0.8版本或0.10.x否则可用
v8::JSON::Stringify
首先在节点版本7中可用 - 在早期版本中不可用
native-json
包的Native::JSON
单例类将以最有效的方式执行请求,具体取决于构建的Node.js的版本。 如果该方法在该版本的V8中可用,则将调用该方法。 否则, Native::JSON
单例类会回退到从全局上下文中获取JSON
对象。
源代码可在github存储库中找到: node-native-json
以下是如何使用Native::JSON::Parse
的示例:
v8::Local<v8::String> json_string = Nan::New("{ \"JSON\": \"object\" }").ToLocalChecked();
v8::Local<v8::Value> val = Native::JSON::Parse(json_string).ToLocalChecked();
我正在添加这个额外的答案,因为我之前的答案仍然是正确的,但截至目前,可以获得更新更好的答案。
NAN版本2.6.2于2017年4月12日发布。此版本引入了一个新对象Nan::JSON
该Nan::JSON
对象提供由所提供的方法C ++版本JSON
对象在JavaScript中,在某种程度上是由NAN Node.js的支持所有版本的向后兼容。 否则V8会通过v8::JSON
对象公开这些方法。
围绕v8::JSON::Parse
简单包装器。
定义:
Nan::MaybeLocal<v8::Value> Nan::JSON::Parse(v8::Local<v8::String> json_string);
使用JSON.Parse(json_string)
将字符串解析为v8::Value
。
例:
v8::Local<v8::String> json_string = Nan::New("{ \"JSON\": \"object\" }").ToLocalChecked();
Nan::JSON NanJSON;
Nan::MaybeLocal<v8::Value> result = NanJSON.Parse(json_string);
if (!result.IsEmpty()) {
v8::Local<v8::Value> val = result.ToLocalChecked();
}
围绕v8::JSON::Stringify
简单包装器。
定义:
Nan::MaybeLocal<v8::String> Nan::JSON::Stringify(v8::Local<v8::Object> json_object, v8::Local<v8::String> gap = v8::Local<v8::String>());
使用JSON.Stringify(value)
来字符串化v8::Object
。
例:
v8::Local<v8::Object> obj = Nan::To<v8::Object>(val).ToLocalChecked();
Nan::JSON NanJSON;
Nan::MaybeLocal<v8::String> result = NanJSON.Stringify(obj);
if (!result.IsEmpty()) {
v8::Local<v8::String> stringified = result.ToLocalChecked();
}
有关这些方法及其参数的原始V8
版本的更多信息,请参阅V8文档中的V8 JSON
对象。
以上是从NAN文档中解释的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.