SoFunction
Updated on 2025-04-14

JavaScript and C++ implement two-way interaction

In development based on CEF (Chromium Embedded Framework), implementing two-way interaction between JavaScript and C++ is an important part of improving user experience and functional flexibility. CEF provides powerfulCefV8ContextandCefV8HandlerInterface, allowing developers to easily share data and call functions between JavaScript and C++.

This section will explore in-depth how to expose C++ functions to the JavaScript environment, how to call local APIs through JavaScript, and implement methods for reverse calls, and provide detailed implementation solutions and optimization suggestions based on the latest technologies.

1. CefV8Context and CefV8Handler: Expose C++ functions to JavaScript

1.1 The role of CefV8Context

CefV8ContextRepresents the execution environment of JavaScript. Through it, developers can access JavaScript global objects, bind local C++ methods to JavaScript functions for script calls in the page.

1.2 Create CefV8Handler and bind to JavaScript

The developer needs to implement an inheritance fromCefV8HandlerClass for processing calls initiated from JavaScript.

Sample code:

class MyV8Handler : public CefV8Handler {
public:
    bool Execute(const CefString& name,
                 CefRefPtr<CefV8Value> object,
                 const CefV8ValueList& arguments,
                 CefRefPtr<CefV8Value>& retval,
                 CefString& exception) override {
        if (name == "myNativeFunction") {
            // Process parameters            if (() == 1 && arguments[0]->IsString()) {
                std::string arg = arguments[0]->GetStringValue();
                std::cout << "Received from JS: " << arg << std::endl;
                retval = CefV8Value::CreateString("Response from C++");
                return true;
            } else {
                exception = "Invalid arguments";
                return false;
            }
        }
        return false;
    }
    IMPLEMENT_REFCOUNTING(MyV8Handler);
};

1.3 Registering a function in a JavaScript global object

passCefRegisterExtensionMethods register custom extensions into JavaScript global objects.

Sample code:

CefRegisterExtension("v8/test",
    "var myNativeFunction;"
    "if (!myNativeFunction) myNativeFunction = function(arg) {"
    "  native function myNativeFunction(arg);"
    "  return myNativeFunction(arg);"
    "};",
    new MyV8Handler());

How to use JavaScript:

const result = myNativeFunction("Hello from JavaScript");
(result); // Output "Response from C++"

2. JavaScript calls local C++ functions

By bindingCefV8Handler, JavaScript can directly call local C++ methods, which are usually used in the following scenarios:

  • Interact with the local API of the device or system.
  • Get dynamic data and update the page in real time.
  • Calls the complex computational logic provided by C++.

2.1 Parameter passing and type checking

The parameter types supported by CEF include strings, numbers, booleans, arrays, and objects. The developer needs toCefV8Handler::ExecuteCheck the type and number of incoming parameters in the method.

Sample code:

if (() == 2 && arguments[0]->IsInt() && arguments[1]->IsString()) {
    int id = arguments[0]->GetIntValue();
    std::string message = arguments[1]->GetStringValue();
    // Execute local logic}

2.2 Support for asynchronous calls

If the call involves asynchronous tasks (such as network requests or file operations), you can returnPromiseGive to JavaScript.

Sample code:

CefPostTask(TID_FILE, base::Bind([]() {
    // Execute asynchronous tasks    CefPostTask(TID_RENDERER, base::Bind([]() {
        // Notify JavaScript    }));
}));

In JavaScript:

async function callNativeAsync() {
    const result = await myNativeFunction("data");
    (result);
}

3. Reverse communication: Local C++ calls JavaScript

In many cases, the main program needs to notify the page JavaScript, such as handling asynchronous events or updating page content. C++ can be accessed throughCefV8ContextImplement this kind of communication.

3.1 Get JavaScript context and execute functions

C++ can be passedCefFrame::GetMainFrameGet the context of the page and call the JavaScript function.

Sample code:

void CallJavaScriptFunction(CefRefPtr<CefBrowser> browser, const std::string& funcName, const std::string& data) {
    CefRefPtr<CefFrame> frame = browser->GetMainFrame();
    CefRefPtr<CefV8Context> context = frame->GetV8Context();

    if (context->Enter()) {
        CefRefPtr<CefV8Value> global = context->GetGlobal();
        CefRefPtr<CefV8Value> func = global->GetValue(funcName);

        if (func && func->IsFunction()) {
            CefV8ValueList args;
            args.push_back(CefV8Value::CreateString(data));
            func->ExecuteFunction(global, args);
        }

        context->Exit();
    }
}

3.2 Register the receiving function on the page

Page JavaScript defines a function that receives C++ data:

function onNativeMessage(data) {
    ("Received from C++:", data);
}

C++ calls this function:

CallJavaScriptFunction(browser, "onNativeMessage", "Hello from C++");

3.3 Using IPC to cooperate with data delivery

If the call needs to interact with the main process or other processes, you can use the IPC mechanism to pass the data to the rendering process before calling JavaScript.

4. Optimization and best practices of two-way interaction

  • Thread Safety The interaction between JavaScript and C++ may involve multiple threads, and developers need to use the task scheduling methods provided by CEF (such asCefPostTask) Make sure the code runs on the correct thread.

  • Parameter verification and error handling Strictly verify the parameters passed by JavaScript in C++ to avoid crashes caused by illegal input.

  • Performance optimization

    • Avoid frequent cross-process communication, and reduce the number of communications by batching data or message merging.
    • Pass complex data structures using efficient serialization methods such as JSON or Protocol Buffers.
  • Security

    • Limit the scope of C++ methods exposed to JavaScript to avoid potential security risks.
    • Use the sandbox mechanism to isolate the page running environment to prevent malicious scripts from causing damage to the system.

Summarize

Through the powerful tools provided by CEF, developers can easily implement two-way interactions between JavaScript and C++. Designing reasonable interactive interfaces and mechanisms in combination with actual scenarios can not only improve the functionality and user experience of the program, but also provide a good foundation for subsequent function expansion.

This is the article about JavaScript and C++ implementing two-way interaction. For more related content on JavaScript and C++, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!