Home > Enterprise >  Calling function from v8 engine throws error
Calling function from v8 engine throws error

Time:02-25

I am making an application that requires me to call a function within some Javascript code. The problem is, despite looking it up many times, I still get the same error.

No matching function for call to 'v8::Object::Get(v8::Local<v8::Context>&, v8::MaybeLocal<v8::String>)'

I have looked up on several different posts and even the documentation, yet I can't even start to run the function.

Isolate::CreateParams create_params;
        create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator();
        Isolate* isolate = Isolate::New(create_params);
        {
            Isolate::Scope isolate_scope(isolate);
            HandleScope handle_scope(isolate);

            Local<Context> context = Context::New(isolate);
            Context::Scope context_scope(context);
            std::string fileContent = f.getContents("./src/solutions/6t10.js");;

            Local<String> source = String::NewFromUtf8(isolate, cv.stringToChar(fileContent), NewStringType::kNormal).ToLocalChecked();

            Local<Script> script = Script::Compile(context, source).ToLocalChecked();
            MaybeLocal<Value> result = script->Run(context).ToLocalChecked();

            Handle<Object> global = context->Global();
            MaybeLocal<String> strValue = String::NewFromUtf8(isolate, cv.stringToChar("prob" std::to_string(pi)));
            Local<Value> value = global->Get(context, strValue);
            Handle<Function> func = Handle<Function>::Cast(value);
            Handle<Value> args[1] = { global->Get(context, String::NewFromUtf8(isolate, ca)) };
            MaybeLocal<Value> js_result = func->Call(context, global, 1, args);

            v8::String::Utf8Value answer(isolate, js_result.ToLocalChecked());
            answers =*answer;

        }
        isolate->Dispose();
        delete create_params.array_buffer_allocator;

If you can't find the problem I'll ask this, how can I turn a LocalString to LocalValue? Thank you :)

CodePudding user response:

(V8 developer here.) @pm100's comment is spot on: Local and MaybeLocal are not interchangeable, a function that needs the former can't deal with the latter.

The "Maybe" part of the name indicates that due to some error that may have happened (usually an exception), the value might be nonexistent. The required explicit conversion helps you to ensure that you don't forget to check for this. (Many years ago, V8's API didn't have this distinction, and it was an endless source of bugs in embedder code.)

how can I turn a Local to Local?

I guess you mean "how can I turn a MaybeLocal into a Local?".

There are two options for different scenarios, and your code already contains an example for one of them:
MaybeLocal::ToLocalChecked() checks if a value is present, crashes the process if not, and returns a Local otherwise. This is, unsurprisingly, appropriate when you can guarantee that no exception happened, e.g. for string allocations.
MaybeLocal::ToLocal(Local* ...) is for cases where you can't guarantee that a value is present (i.e. no exception happened) and you don't want to crash the process. It checks whether a value is present, returns false if not (so you can gracefully handle that case), and populates the Local in the out-parameter otherwise (and returns true). This is typically used for any values returned from JavaScript. As a specific example in your code: js_result.ToLocalChecked() will crash the process if func->Call threw an exception.

  •  Tags:  
  • c v8
  • Related