我如何将 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