我如何将 c 指针指向 v8::object 的值
How can i point the c pointer to v8::object's value
我想使用 char *p
指向对象[键],但是无法获取值。
测试代码
// hello.cc
#include <v8.h>
#include <node.h>
namespace demo
{
using v8::ArrayBuffer;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Uint8Array;
using v8::Value;
static void getObjectValue(void *object, const char *key, char **value)
{
Object *obj = (Object *)object;
Isolate *isolate = obj->GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<Value> lKey = String::NewFromUtf8(isolate, key, NewStringType::kNormal).ToLocalChecked();
Local<Value> lValue = obj->Get(context, lKey).ToLocalChecked();
String::Utf8Value u8Str(isolate, lValue); // local value destory after call, so i can't get the value.
*value = *u8Str;
}
void Method(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<Object> object = args[0]->ToObject(context).ToLocalChecked();
const char *key = "key";
char *p = NULL;
char **value = &p;
getObjectValue((void *)*object, key, value);
printf("value: %s\n", p);
}
void Initialize(Local<Object> exports)
{
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace demo
// hello.js
const obj = require("./build/Release/addon.node");
console.log(obj.hello({"key": "aaa"}));
## binding.gyp
{
"targets": [
{
"target_name": "addon",
"sources": [ "hello.cc" ]
}
]
}
我怎样才能得到正确的值???
谢谢
您不能使用原始指针指向 V8 堆上的东西(对象、字符串...)。原因是垃圾收集器可以四处移动对象,这会破坏您的指针。这就是为什么 V8 在其 API 上使用 "handles",这是一种 GC 安全的方式来引用堆上的对象。这意味着您将使用 v8::Local<v8::String>
指向 V8 堆上的字符串。如果您需要句柄的寿命比当前 HandleScope
的范围更长,则可以使用 v8::Persistent<v8::String>
.
当然,您可以使用 String::Utf8Value
在本地函数中获取原始字符数据,就像您已经想到的那样。那时你可以复制它,或者比较它,或者 运行 任何其他(只读)字符串操作(如果你修改它,V8 会以有趣的方式混淆)。如果你想保持标准 C++ 数据结构的价值,你可以例如从中构建一个 std::string
。
我想使用 char *p
指向对象[键],但是无法获取值。
测试代码
// hello.cc
#include <v8.h>
#include <node.h>
namespace demo
{
using v8::ArrayBuffer;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Uint8Array;
using v8::Value;
static void getObjectValue(void *object, const char *key, char **value)
{
Object *obj = (Object *)object;
Isolate *isolate = obj->GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<Value> lKey = String::NewFromUtf8(isolate, key, NewStringType::kNormal).ToLocalChecked();
Local<Value> lValue = obj->Get(context, lKey).ToLocalChecked();
String::Utf8Value u8Str(isolate, lValue); // local value destory after call, so i can't get the value.
*value = *u8Str;
}
void Method(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<Object> object = args[0]->ToObject(context).ToLocalChecked();
const char *key = "key";
char *p = NULL;
char **value = &p;
getObjectValue((void *)*object, key, value);
printf("value: %s\n", p);
}
void Initialize(Local<Object> exports)
{
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace demo
// hello.js
const obj = require("./build/Release/addon.node");
console.log(obj.hello({"key": "aaa"}));
## binding.gyp
{
"targets": [
{
"target_name": "addon",
"sources": [ "hello.cc" ]
}
]
}
我怎样才能得到正确的值???
谢谢
您不能使用原始指针指向 V8 堆上的东西(对象、字符串...)。原因是垃圾收集器可以四处移动对象,这会破坏您的指针。这就是为什么 V8 在其 API 上使用 "handles",这是一种 GC 安全的方式来引用堆上的对象。这意味着您将使用 v8::Local<v8::String>
指向 V8 堆上的字符串。如果您需要句柄的寿命比当前 HandleScope
的范围更长,则可以使用 v8::Persistent<v8::String>
.
当然,您可以使用 String::Utf8Value
在本地函数中获取原始字符数据,就像您已经想到的那样。那时你可以复制它,或者比较它,或者 运行 任何其他(只读)字符串操作(如果你修改它,V8 会以有趣的方式混淆)。如果你想保持标准 C++ 数据结构的价值,你可以例如从中构建一个 std::string
。