You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CEF开发:如何获取JavaScript代码中的变量值传递到C++变量

CEF JS变量回传C++实现方案

CEF完全支持将JavaScript上下文内的变量值提取到C变量中,直接调用CefFrame::ExecuteJavaScript属于单向执行逻辑,没有设计返回值接收通道,因此执行产生的局部变量不会自动同步到C侧,可通过以下两种成熟方案实现取值:

方案1:V8窗口绑定回调(适配同渲染进程取值场景)

这是适配你当前需求最轻量化的方案,核心逻辑是提前在JS上下文挂载C++实现的回调函数,JS侧拿到目标值后主动调用回调传参:

  • 实现自定义CefV8Handler类,重写Execute方法接收JS传入的参数
  • 在渲染进程的上下文创建回调OnContextCreated中,将C++方法绑定到JS的window全局对象
  • 修改待执行的JS代码,拿到rect.x后调用绑定好的全局函数传值
  • C++侧在回调中解析参数,直接赋值给目标int变量

核心代码示例:

  1. 自定义V8回调处理器
class RectRecvHandler : public CefV8Handler {
public:
    int* output_rect_x;
    explicit RectRecvHandler(int* rect_x_ptr):output_rect_x(rect_x_ptr) {}

    bool Execute(const CefString& func_name,
                CefRefPtr<CefV8Value> caller,
                const CefV8ValueList& args,
                CefRefPtr<CefV8Value>& ret_val,
                CefString& err) override {
        if (func_name == "sendRectToCpp" && args.size() >= 1 && args[0]->IsInt()) {
            *output_rect_x = args[0]->GetIntValue();
            return true;
        }
        return false;
    }
    IMPLEMENT_REFCOUNTING(RectRecvHandler);
};
  1. 上下文初始化阶段绑定函数到window
void CustomRenderHandler::OnContextCreated(CefRefPtr<CefBrowser> browser,
                                           CefRefPtr<CefFrame> frame,
                                           CefRefPtr<CefV8Context> context) {
    CefRefPtr<CefV8Value> global_obj = context->GetGlobal();
    // 传入你要赋值的C++ int变量地址
    CefRefPtr<CefV8Handler> recv_handler = new RectRecvHandler(&rect_x);
    CefRefPtr<CefV8Value> js_bind_func = CefV8Value::CreateFunction("sendRectToCpp", recv_handler);
    global_obj->SetValue("sendRectToCpp", js_bind_func, V8_PROPERTY_ATTRIBUTE_NONE);
}
  1. 修改原有JS执行代码
frame->GetMainFrame()->ExecuteJavaScript(
    R"(
        const elem = document.getElementsByClassName("my_class")[0];
        const rect = elem.getBoundingClientRect();
        alert(rect.x + ":" + rect.y);
        // 调用绑定函数传值,rect.x为浮点数,先取整转成int
        window.sendRectToCpp(Math.round(rect.x));
    )", "", 1);

方案2:CEF消息路由(适配跨进程取值场景)

如果你需要把渲染进程拿到的rect值传到浏览器进程的C++变量中,可以直接用CEF内置的消息路由器,不用手动写V8绑定:

  • 初始化时配置CefMessageRouterConfig,分别在浏览器进程、渲染进程注册路由实例
  • JS侧拿到rect.x后调用window.cefQuery发送异步消息,把值作为请求参数传入
  • 浏览器进程重写CefMessageRouterBrowserSide::Handler的OnQuery方法,解析参数即可拿到目标值

注意:getBoundingClientRect()返回的坐标值是浮点数类型,传给C++int变量前必须在JS侧做取整转换,否则会出现参数类型不匹配、取值失败的问题。

内容的提问来源于stack exchange,提问作者Optimus1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:09:24