oopベースのアプリケーションでC++でv8を使用したいのですが、コード内にv8オブジェクトのスコープに関するいくつかの問題があります。私はクラス(または名前空間)にオブジェクトのいくつかが壊れてしまいます。oopアプリケーションでV8エンジンを使用する
このコードは、エラーのない作品は以下となります。
//#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <v8.h>
#include <libplatform.h>
using namespace v8;
Handle<v8::Object> g_global;
// Reads a file into a v8 string.
v8::Handle<v8::String> _ReadFile(const char* name)
{
#pragma warning(disable : 4996)
FILE* file = fopen(name, "rb");
if (file == NULL) return v8::Handle<v8::String>();
fseek(file, 0, SEEK_END);
int size = ftell(file);
rewind(file);
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;)
{
int read = fread(&chars[i], 1, size - i, file);
i += read;
}
fclose(file);
v8::Handle<v8::String> result = v8::String::NewFromUtf8(g_global->GetIsolate(), chars);
delete[] chars;
return result;
}
Handle<v8::Value> CallJSFunction(std::string funcName, Handle<Value> argList[], unsigned int argCount) {
Handle<v8::Object> global = g_global;
// Create value for the return of the JS function
Handle<Value> js_result;
// Grab JS function out of file
Handle<v8::Value> value = global->Get(String::NewFromUtf8(global->GetIsolate(), funcName.c_str()));
// Cast value to v8::Function
Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(value);
// Call function with all set values
js_result = func->Call(global, argCount, argList);
// Return value from function
return js_result;
}
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
virtual void *Allocate(size_t length) {
void *data = AllocateUninitialized(length);
return data == NULL ? data : memset(data, 0, length);
}
virtual void *AllocateUninitialized(size_t length) { return malloc(length); }
virtual void Free(void *data, size_t) { free(data); }
};
int main(int argc, char* argv[])
{
// Initialize V8.
V8::InitializeICU();
V8::InitializeExternalStartupData(argv[0]);
Platform* platform = platform::CreateDefaultPlatform();
V8::InitializePlatform(platform);
V8::Initialize();
// Create a new Isolate and make it the current one.
ArrayBufferAllocator allocator;
Isolate::CreateParams create_params;
create_params.array_buffer_allocator = &allocator;
Isolate* isolate = Isolate::New(create_params);
Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
HandleScope handle_scope(isolate);
// Create a new context.
Local<Context> context = Context::New(isolate);
// Enter the context for compiling and running the hello world script.
Context::Scope context_scope(context);
g_global = context->Global();
// Try to include this js file into current context
Local<String> source = _ReadFile(R"(somjsfile.js)");
Local<Script> script = Script::Compile(context, source).ToLocalChecked();
script->Run();
//
// functionName is a valid js code inside somjsfile.js file i test it and it's ok.
//
Handle<Value> js_result = CallJSFunction("functionName", nullptr, 0);
String::Utf8Value utf8(js_result);
printf("%s\n", *utf8);
}
// Dispose the isolate and tear down V8.
isolate->Dispose();
V8::Dispose();
V8::ShutdownPlatform();
delete platform;
return 0;
}
しかし、私はこのようなクラス内のコードを置けば、私はCallJSFunction()
を呼び出すことはできません。
いくつかのオブジェクトにアクセスすることはできませんので、またはそれはあなたがあなたのクラスでv8::Local<...>
オブジェクトを入れているが、v8::Local
年代はの範囲内でのみ有効ですヌル
#pragma once
#include "Common.h"
#include <v8.h>
#include <libplatform.h>
using namespace v8;
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
virtual void *Allocate(size_t length) {
void *data = AllocateUninitialized(length);
return data == NULL ? data : memset(data, 0, length);
}
virtual void *AllocateUninitialized(size_t length) { return malloc(length); }
virtual void Free(void *data, size_t) { free(data); }
};
class JSUtil
{
private:
v8::Isolate * m_Isolate;
v8::Handle<v8::Object> m_global;
v8::Local<v8::Context> m_Context;
v8::Platform* m_platform;
std::string LoadFileAsString(const char* name)
{
#pragma warning(disable : 4996)
FILE* file = fopen(name, "rb");
if (file == nullptr)
return nullptr;
fseek(file, 0, SEEK_END);
int size = ftell(file);
rewind(file);
char* chars = new char[size + 1];
chars[size] = '\0';
for (int i = 0; i < size;)
{
int read = fread(&chars[i], 1, size - i, file);
i += read;
}
fclose(file);
std::string result = std::string(chars);
delete[] chars;
return result;
}
bool InitV8Engine()
{
std::string exepath = R"(fullpath_of_exename)";
// Initialize V8.
v8::V8::InitializeICU();
v8::V8::InitializeExternalStartupData(exepath.c_str());
m_platform = v8::platform::CreateDefaultPlatform();
v8::V8::InitializePlatform(m_platform);
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
ArrayBufferAllocator allocator;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = &allocator;
m_Isolate = v8::Isolate::New(create_params);
v8::Isolate::Scope isolate_scope(m_Isolate);
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(m_Isolate);
// Create a new context.
m_Context = v8::Context::New(m_Isolate);
// Enter the context for compiling and running the hello world script.
v8::Context::Scope context_scope(m_Context);
IncludeJSFile(m_Context->Global());
return true;
}
bool Shutdown()
{
// Dispose the isolate and tear down V8.
m_Isolate->Dispose();
V8::Dispose();
V8::ShutdownPlatform();
delete m_platform;
}
bool IncludeJSFile(v8::Handle<v8::Object> global)
{
//
// Try to include this js file into current context
//
// Create a string containing the JavaScript source code.
std::string FileBuff = LoadFileAsString(R"(somjsfile.js)");
v8::Local<v8::String> source = v8::String::NewFromUtf8(global->GetIsolate(), FileBuff.c_str());
// Compile the source code.
v8::Local<v8::Script> script = v8::Script::Compile(m_Context, source).ToLocalChecked();
// Run the script to get the result.
script->Run();
return true;
}
v8::Handle<v8::Value> CallJSFunction(std::string funcName, v8::Handle<v8::Value> argList[], unsigned int argCount)
{
v8::Handle<v8::Object> global = m_global;
// Create value for the return of the JS function
v8::Handle<v8::Value> js_result;
v8::Local<v8::String> tmp = v8::String::NewFromUtf8(global->GetIsolate(), funcName.c_str());
// Grab JS function out of file
v8::Handle<v8::Value> value = global->Get(tmp);
// Cast value to v8::Function
v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(value);
// Call function with all set values
js_result = func->Call(global, argCount, argList);
// Return value from function
return js_result;
}
public:
JSUtil()
{
InitV8Engine();
}
~JSUtil()
{
Shutdown();
}
};
2番目のコードでは、すべての関数呼び出しに対して新しいコンテキストを明示的に作成していますが、元の分離していないアプローチはそうではないと思いますか? – kfsone
問題を再現する[MVCE]を提供するために、コードの壁を小さくしてください。 –
@kfsoneそれは私のコピーコードの間違いだった、私はそれを編集する。 –