v8 - 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
解决方案
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.
推荐阅读
- azure - 是否可以在 azure web 应用程序中创建主机文件的等价物
- java - 一个数据流作业内的并行管道
- python - 如何解决OSError: [WinError 123] The filename, directory name, or volume label syntax is wrong in pycharm 错误
- c# - 室内寻路 c# wpf
- c - 是否可以在运行时在内部闪存 EEprom 中写入 Cert.der 和 key.der?我正在使用 stm32
- iis - 如何将 SSL 证书绑定到 IIS 上的特定端口?
- flutter - 应该如何使用flutter_web_test包对flutter_web项目进行单元测试?
- django - 如何遍历模板中的 url
- json - 使用 PUT 方法更新 JSON 中的值
- mysql - sequelize.js的日志查询结果