使用 v8 读取二进制文件的函数
Function to read binary files using v8
我正在使用 QT 和 v8 开发一个 Javascript 解释器。
我需要创建一个可以从指定路径读取二进制文件的函数。
这是我的 C++ 代码:
void ScriptThread::ReadFile(const v8::FunctionCallbackInfo<v8::Value>& args)
{
if (v8::V8::IsExecutionTerminating(args.GetIsolate()) || instance->m_killFlag)
return;
v8::HandleScopehandle_scope(args.GetIsolate());
if (args.Length() != 1)
{
args.GetIsolate()->ThrowException(
v8::String::NewFromUtf8(args.GetIsolate(), "Bad parameters"));
return;
}
v8::String::Utf8Value str(args[0]);
QString filepath = *str;
QFile file(filepath);
if (!file.open(QFile::ReadOnly))
{
return;
}
QByteArray data = file.readAll();
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(args.GetIsolate(), (void*)data.data(), data.size());
args.GetReturnValue().Set(ab);
}
问题是在Javascript中调用这个函数后,js文件中的ArrayBuffer包含的是随机数据而不是文件内容
这是我的 JS 代码:
var buffer = ReadFile("D:/Temp/myfolder/ascii.txt")
Log(buffer)
var view = new Uint8Array(buffer)
Log(view)
Log(String.fromCharCode.apply(null, view))
D:/Temp/myfolder/ascii.txt:
ABCDEF
和我的 JS 在 运行 脚本多次不更改文件路径后的输出:
2016-09-15 12:42:35.847 Script Info [object ArrayBuffer]
2016-09-15 12:42:35.847 Script Info 200,29,125,195,254,136
2016-09-15 12:42:35.847 Script Info È}Ãþ
2016-09-15 12:42:35.847 Info Script Stopped
2016-09-15 12:43:41.543 Script Info [object ArrayBuffer]
2016-09-15 12:43:41.543 Script Info 238,254,238,254,238,254
2016-09-15 12:43:41.543 Script Info îþîþîþ
2016-09-15 12:43:41.543 Info Script Stopped
2016-09-15 12:47:19.588 Script Info [object ArrayBuffer]
2016-09-15 12:47:19.588 Script Info m
2016-09-15 12:47:19.588 Script Info 30,25,109,30,0,0
2016-09-15 12:47:19.588 Info Script Stopped
我从我的 cpp 文件中检查了 v8::ArrayBuffer 中的数据。
我不能使用字符串,因为读取非人类可读文件需要该函数,而且我不想在我的项目中包含 node.js。
不知何故 ArrayBuffer 在 return 之前被 GC 了?还是我不知何故超出了范围?
你们能帮帮我吗?
谢谢!
我对 QT 了解不多,但看起来你正在将数组缓冲区指向堆栈上变量的数据
QByteArray data = file.readAll();
可能(我不知道 QByteArray)在您 return 创建数组缓冲区后被清理。
来自http://v8.paulfryzel.com/docs/master/classv8_1_1_array_buffer.html:
Create a new ArrayBuffer over an existing memory block. The created
array buffer is by default immediately in externalized state. The
memory block will not be reclaimed when a created ArrayBuffer is
garbage-collected.
所以我很确定它依赖于你来确保它指向的内存保持有效,但我认为你没有这样做。
我正在使用 QT 和 v8 开发一个 Javascript 解释器。
我需要创建一个可以从指定路径读取二进制文件的函数。
这是我的 C++ 代码:
void ScriptThread::ReadFile(const v8::FunctionCallbackInfo<v8::Value>& args)
{
if (v8::V8::IsExecutionTerminating(args.GetIsolate()) || instance->m_killFlag)
return;
v8::HandleScopehandle_scope(args.GetIsolate());
if (args.Length() != 1)
{
args.GetIsolate()->ThrowException(
v8::String::NewFromUtf8(args.GetIsolate(), "Bad parameters"));
return;
}
v8::String::Utf8Value str(args[0]);
QString filepath = *str;
QFile file(filepath);
if (!file.open(QFile::ReadOnly))
{
return;
}
QByteArray data = file.readAll();
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(args.GetIsolate(), (void*)data.data(), data.size());
args.GetReturnValue().Set(ab);
}
问题是在Javascript中调用这个函数后,js文件中的ArrayBuffer包含的是随机数据而不是文件内容
这是我的 JS 代码:
var buffer = ReadFile("D:/Temp/myfolder/ascii.txt")
Log(buffer)
var view = new Uint8Array(buffer)
Log(view)
Log(String.fromCharCode.apply(null, view))
D:/Temp/myfolder/ascii.txt:
ABCDEF
和我的 JS 在 运行 脚本多次不更改文件路径后的输出:
2016-09-15 12:42:35.847 Script Info [object ArrayBuffer]
2016-09-15 12:42:35.847 Script Info 200,29,125,195,254,136
2016-09-15 12:42:35.847 Script Info È}Ãþ
2016-09-15 12:42:35.847 Info Script Stopped
2016-09-15 12:43:41.543 Script Info [object ArrayBuffer]
2016-09-15 12:43:41.543 Script Info 238,254,238,254,238,254
2016-09-15 12:43:41.543 Script Info îþîþîþ
2016-09-15 12:43:41.543 Info Script Stopped
2016-09-15 12:47:19.588 Script Info [object ArrayBuffer]
2016-09-15 12:47:19.588 Script Info m
2016-09-15 12:47:19.588 Script Info 30,25,109,30,0,0
2016-09-15 12:47:19.588 Info Script Stopped
我从我的 cpp 文件中检查了 v8::ArrayBuffer 中的数据。
我不能使用字符串,因为读取非人类可读文件需要该函数,而且我不想在我的项目中包含 node.js。
不知何故 ArrayBuffer 在 return 之前被 GC 了?还是我不知何故超出了范围? 你们能帮帮我吗?
谢谢!
我对 QT 了解不多,但看起来你正在将数组缓冲区指向堆栈上变量的数据
QByteArray data = file.readAll();
可能(我不知道 QByteArray)在您 return 创建数组缓冲区后被清理。
来自http://v8.paulfryzel.com/docs/master/classv8_1_1_array_buffer.html:
Create a new ArrayBuffer over an existing memory block. The created array buffer is by default immediately in externalized state. The memory block will not be reclaimed when a created ArrayBuffer is garbage-collected.
所以我很确定它依赖于你来确保它指向的内存保持有效,但我认为你没有这样做。