首页 > 解决方案 > How can i point the c pointer to v8::object's value

问题描述

i want to use char *p point to object[key], but is can't get the value.

test code

// 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" ]
    }
  ]
}

How can i get the correct value???

thank

标签: v8

解决方案


You can't use raw pointers to point to things (objects, strings, ...) on V8's heap. The reason is that the garbage collector could move objects around, which would break your pointers. That's why V8 uses "handles" on its API, which are a GC-safe way to refer to objects on the heap. That means you'd use v8::Local<v8::String> to point at a string on V8's heap. If you need the handle to be longer lived than the scope of your current HandleScope, you can use a v8::Persistent<v8::String>.

Of course you can get at the raw character data within a local function, with String::Utf8Value just like you've figured out. At that time you can copy it, or compare it, or run any other (read-only) string operation on it (if you modify it, V8 will get confused in interesting ways). If you want to keep the value in terms of standard C++ data structures, you could e.g. construct a std::string from it.


推荐阅读