Calling a v8 javascript function from c++ with an argument

一世执手 提交于 2019-11-28 17:31:04

I haven't tested this, but it's possible that something like this will work:

// ...define and compile "test_function"

Handle<v8::Object> global = context->Global();
Handle<v8::Value> value = global->Get(String::New("test_function")); 

if (value->IsFunction()) {
    Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(value);
    Handle<Value> args[2];
    args[0] = v8::String::New("value1");
    args[1] = v8::String::New("value2");

    Handle<Value> js_result = func->Call(global, 2, args);

    if (js_result->IsInt32()) {
        int32_t result = js_result->ToInt32().Value();
        // do something with the result
    }
}

Edit:

It looks like your javascript function expects a single argument (consisting of an array of two values), but it kinda looks like we're calling func by passing in two arguments.

To test this hypothesis, you could change your javascript function to take two arguments and compare them, e.g.:

function test_function(test_arg1, test_arg2) { 
  var match = 0; 
  if (test_arg1 == test_arg2) { 
    match = 1; 
  } else { 
    match = 0; 
  } 
  return match; 
}

Another simpler method is as follows:

Handle<String> code = String::New(
  "(function(arg) {\n\
     console.log(arg);\n\
    })");
Handle<Value> result = Script::Compile(code)->Run();
Handle<Function> function = Handle<Function>::Cast(result);

Local<Value> args[] = { String::New("testing!") };
func->Call(Context::GetCurrent()->Global(), 1, args);

Essentially compile some code that returns an anonymous function, then call that with whatever arguments you want to pass.

For new version of v8, you can use v8::Object::CallAsFunction or v8::Function::Call to call a javascript function. Here is an example for recent version (7.4.x)

#include <iostream>
#include <libplatform/libplatform.h>
#include <v8.h>

int main(int argc, char* argv[])
{
    v8::V8::InitializeICUDefaultLocation(argv[0]);
    v8::V8::InitializeExternalStartupData(argv[0]);
    std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
    v8::V8::InitializePlatform(platform.get());
    v8::V8::Initialize();

    v8::Isolate::CreateParams createParams;
    createParams.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
    v8::Isolate* isolate = v8::Isolate::New(createParams);

    std::cout << v8::V8::GetVersion() << std::endl;

    {
        v8::Isolate::Scope isolate_scope(isolate);
        v8::HandleScope handle_scope(isolate);

        v8::Local<v8::Context> context = v8::Context::New(isolate);
        v8::Context::Scope context_scope(context);

        v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "var foo=function(){return 'foo get called';}");
        v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();

        v8::TryCatch tryCatch(isolate);
        v8::MaybeLocal<v8::Value> result = script->Run(context);
        if (result.IsEmpty()) {
            v8::String::Utf8Value e(isolate, tryCatch.Exception());
            std::cerr << "Exception: " << *e << std::endl;
        } else {
            v8::String::Utf8Value r(isolate, result.ToLocalChecked());
            std::cout << *r << std::endl;
        }

        v8::Local<v8::Value> foo_value = context->Global()->Get(v8::String::NewFromUtf8(isolate, "foo"));
        if (foo_value->IsFunction()) {
            v8::Local<v8::Value> foo_ret = foo_value->ToObject(isolate)->CallAsFunction(context, context->Global(), 0, nullptr).ToLocalChecked();
            v8::String::Utf8Value utf8Value(isolate, foo_ret);
            std::cout << "CallAsFunction result: " << *utf8Value << std::endl;

            v8::Local<v8::Object> foo_object = foo_value->ToObject(isolate);
            v8::Local<v8::Value> foo_result = v8::Function::Cast(*foo_object)->Call(context, context->Global(), 0, nullptr).ToLocalChecked();
            std::cout << "Call result: "  << *(v8::String::Utf8Value(isolate, foo_result)) << std::endl;
        } else {
            std::cerr << "foo is not a function" << std::endl;
        }
    }

    isolate->Dispose();
    v8::V8::Dispose();
    v8::V8::ShutdownPlatform();
    delete createParams.array_buffer_allocator;

    return EXIT_SUCCESS;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!