簡體   English   中英

從 c++ 調用 v8 中的 JS 函數

[英]Call JS functions in v8 from c++

我想要做的是從 c++ 調用 JS/v8 中已編譯的函數。我正在為我正在編寫的游戲引擎執行此操作,該引擎使用 V8 作為腳本后端。

這是為我的引擎格式化腳本的方式:

function init(){ //this gets called at the startup of the game
    print("wambo");
}

var time = 0;
function tick(delta){ //this gets called every frame
    time += delta;
    print("pop");
}

我已經嘗試查看此編譯文檔https://v8docs.nodesource.com/node-16.13/df/d69/classv8_1_1_context.html中的 function in v8::Local<v8::Context>->Global that Get functions按名稱,來自已編譯的 JS,但我無法理解密鑰系統。

我嘗試通讀Calling a v8 javascript function from c++ with argument ,但這些示例對於 2022 年最新版本的 v8 來說似乎已經過時。

我確實將示例從其他答案移植到最新的 V8 版本 - 10.1.72

// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libplatform/libplatform.h"
#include "v8.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char jsCode[] = "var foo = function(arg) {"
                      "if (Math.random() > 0.5) throw new Error('er');"
                      "return arg + ' with foo from JS';"
                      "}";

int main(int argc, char *argv[]) {
    // Initialize V8.
    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();

    // Create a new Isolate and make it the current one.
    v8::Isolate::CreateParams create_params;
    create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
    v8::Isolate *isolate = v8::Isolate::New(create_params);
    {
        v8::Isolate::Scope isolate_scope(isolate);
        v8::HandleScope handle_scope(isolate);

        // Create a context and load the JS code into V8
        v8::Local<v8::Context> context = v8::Context::New(isolate);
        v8::Context::Scope context_scope(context);
        v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, jsCode, v8::NewStringType::kNormal).ToLocalChecked();
        v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
        v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
        v8::String::Utf8Value utf8(isolate, result);

        // This is the result of the evaluation of the code (probably undefined)
        printf("%s\n", *utf8);

        // Take a reference to the created JS function and call it with a single string argument
        v8::Local<v8::Value> foo_value = context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "foo").ToLocalChecked()).ToLocalChecked();
        if (foo_value->IsFunction()) {
            // argument (string)
            v8::Local<v8::Value> foo_arg = v8::String::NewFromUtf8(isolate, "arg from C++").ToLocalChecked();

            {
                // Method 1
                v8::TryCatch trycatch(isolate);
                v8::MaybeLocal<v8::Value> foo_ret = foo_value.As<v8::Object>()->CallAsFunction(context, context->Global(), 1, &foo_arg);
                if (!foo_ret.IsEmpty()) {
                    v8::String::Utf8Value utf8Value(isolate, foo_ret.ToLocalChecked());
                    std::cout << "CallAsFunction result: " << *utf8Value << std::endl;
                } else {
                    v8::String::Utf8Value utf8Value(isolate, trycatch.Message()->Get());
                    std::cout << "CallAsFunction didn't return a value, exception: " << *utf8Value << std::endl;
                }
            }

            {
                // Method 2
                v8::TryCatch trycatch(isolate);
                v8::Local<v8::Object> foo_object = foo_value.As<v8::Object>();
                v8::MaybeLocal<v8::Value> foo_result = v8::Function::Cast(*foo_object)->Call(context, context->Global(), 1, &foo_arg);
                if (!foo_result.IsEmpty()) {
                    std::cout << "Call result: " << *(v8::String::Utf8Value(isolate, foo_result.ToLocalChecked())) << std::endl;
                } else {
                    v8::String::Utf8Value utf8Value(isolate, trycatch.Message()->Get());
                    std::cout << "CallAsFunction didn't return a value, exception: " << *utf8Value << std::endl;
                }
            }
        } else {
            std::cerr << "foo is not a function" << std::endl;
        }
    }

    // Dispose the isolate and tear down V8.
    isolate->Dispose();
    v8::V8::Dispose();
    v8::V8::ShutdownPlatform();
    delete create_params.array_buffer_allocator;
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM