V8 C++ embedding issues

2019-08-07 11:40发布

问题:

I am new to V8 embedding, and have just started to replace my current scripting language with the V8 library. However I am running into some really odd (For me at least) issues. It kinda feels like I am the only one doing what I am doing and I feel like I am doing something stupid.

I have made a wrapper class to wrap V8 engine functions and to construct the engine when my wrapper is constructed (Try to ignore shitty variable names or silly styles):

engine.h:

namespace JSEngine {

class Engine
{
    public:
        Engine();
        virtual ~Engine();
        v8::Isolate* isolate;
        v8::Handle<v8::Context> context;
};
}

engine.cpp (Which includes engine.h):

JSEngine::Engine::Engine()
{   
    v8::Locker locker();
    V8::Initialize();

    this->isolate = Isolate::GetCurrent();
    HandleScope scope(this->isolate);

    this->context = Context::New(this->isolate);
}

That code is fine and dandy, however once I try this:

Server::jsEngine = new JSEngine::Engine();
HandleScope scope(Server::jsEngine->isolate);
Context::Scope context_scope(Server::jsEngine->context);

Handle<String> source = String::NewFromUtf8(Server::jsEngine->isolate, "'Hello' + ', World!'");
Handle<Script> script = Script::Compile(source);
Handle<Value> result = script->Run();

String::Utf8Value utf8(result);
printf("%s\n", *utf8);

I get SEGMENTATION FAULT on this line: Context::Scope context_scope(Server::jsEngine->context);

I have no idea what I am doing wrong or if this approach is even best practice. Could you help me solve the SEGMENTATION FAULT error please?

回答1:

Your context member variable is a local handle, created in the local scope and is invalid as soon as your Engine constructor completes because the scope is deleted. You need a persistent handle for your context. Change your Engine declaration to use

v8::Persistent<v8::Context> context;

and when you actually create the context, use

this->context.Reset(this->isolate, Context::New(this->isolate));

and in your destructor, use

this->context.Reset();