CEF3、C和JS在开发中如何协同工作以提升应用性能?

CEF3(Chromium Embedded Framework)中,JavaScript与C++的交互是一个复杂但功能强大的特性,通过这种交互,开发者可以在客户端应用程序中充分利用JavaScript的灵活性和C++的性能优势,以下是关于CEF3中JS与C++交互的详细解析:

一、基本概念

cef3 c js

1、V8引擎

CEF3使用V8 JavaScript引擎来执行内部的JavaScript代码,每一个Frame在浏览器进程中都有一个属于自己的JS上下文,该上下文提供了一个安全和有限的环境来执行JS代码。

2、渲染进程

Chromium和CEF使用V8引擎运行在独立的渲染进程中,渲染进程中的主线程命名为TID_RENDERER,所有的V8运行在这个线程中。

3、回调机制

JS APIs被设计成通过异步回调方法在浏览器和渲染进程之间通讯。

二、执行JavaScript

在客户端执行JavaScript最简单的方法是使用CefFrame::ExecuteJavaScript()函数,该函数在浏览器和渲染进程中都可以使用,并且能在JS上下文之外使用。

CefRefPtr<CefBrowser> browser = ...;
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
frame->ExecuteJavaScript("alert('ExecuteJavaScript works!');", frame->GetURL(), 0);

上述代码将在browser的主Frame中弹出一个对话框,显示“ExecuteJavaScript works!”。

三、窗口绑定

窗口绑定允许客户端应用程序将值附加到一个框架窗口对象上,窗口绑定使用CefRenderProcessHandler::OnContextCreated()方法实现。

cef3 c js
void MyRenderProcessHandler::OnContextCreated(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefV8Context> context) {
    // Retrieve the context's window object.
    CefRefPtr<CefV8Value> object = context->GetGlobal();
    // Create a new V8 string value.
    CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");
    // Add the string to the window object as "window.myval".
    object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);
}

JavaScript代码可以与窗口绑定相配合使用:

<script language="JavaScript">
alert(window.myval); // Shows an alert box with "My Value!"
</script>

四、扩展

扩展和窗口绑定类似,除了在每个框架的上下文中加载和加载后不能修改,当扩展加载后DOM不存在和在扩展加载期间试图访问DOM将会导致崩溃,扩展使用CefRegisterExtension()函数注册,在CefRenderProcessHandler::OnWebKitInitialized()方法中调用。

void MyRenderProcessHandler::OnWebKitInitialized() {
    // Define the extension contents.
    std::string extensionCode =
    "var test;"
    "if (!test)"
    " test = {};"
    "(function() {"
    " test.myval = 'My Value!';"
    "})();";
    // Register the extension.
    CefRegisterExtension("v8/test", extensionCode, NULL);
}

JavaScript代码可以与扩展相配合使用:

<script language="JavaScript">
alert(test.myval); // Shows an alert box with "My Value!"
</script>

五、基本的JS类型

CEF支持创建JS基本数据类型,包括undefined, null, bool, int, double, date和string,这些类型使用CefV8Value::Create*()静态方法创建,创建一个新的JS string类型使用CreateString()方法。

CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");

六、JS简单回调

本地代码可以通过ExecuteFunction()ExecuteFunctionWithContext()执行JS函数。

void MyRenderProcessHandler::OnContextCreated(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefV8Context> context) {
    // Retrieve the context's window object.
    CefRefPtr<CefV8Value> object = context->GetGlobal();
    CefRefPtr<CefV8Handler> handler = new MyV8Handler(this);
    object->SetValue("register", CefV8Value::CreateFunction("register", handler), V8_PROPERTY_ATTRIBUTE_NONE);
}

MyV8Handler::Execute()的实现中对"register"的context和function保存引用。

bool MyV8Handler::Execute(const CefString& name,
                          CefRefPtr<CefV8Value> object,
                          const CefV8ValueList& arguments,
                          CefRefPtr<CefV8Value>& retval,
                          CefString& exception) {
    if (name == "register") {
        if (arguments.size() == 1 && arguments[0]->IsFunction()) {
            callback_func_ = arguments[0];
            callback_context_ = CefV8Context::GetCurrentContext();
            return true;
        }
    }
    return false;
}

通过JavaScript注册JS callback。

function myFunc() {
    // do something in JS.
}
window.register(myFunc);

在随后的某个时候执行JS callback。

CefV8ValueList args;
CefRefPtr<CefV8Value> retval;
CefString exception;
if (callback_func_->ExecuteFunctionWithContext(callback_context_, NULL, args, retval, exception, false)) {
    if (exception.get()) {
        // Execution threw an exception.
    } else {
        // Execution succeeded.
    }
}

七、JS异步回调

JavaScript与C++之间可以实现异步通信,但不能跨进程通信,当JavaScript与renderer进行实现异步通信时,可以参考sayHello实现,以下是一个使用JavaScript读取本地文本文件的案例来探索如何在CEF中实现JavaScript与C++之间的跨进程异步调用。

八、FAQs

cef3 c js

1、Q: CEF3中的JS与C++如何进行交互?

A: CEF3中的JS与C++交互主要通过V8 JavaScript引擎实现,可以使用CefFrame::ExecuteJavaScript()函数执行JavaScript代码,或者通过窗口绑定和扩展将值附加到框架窗口对象上,还可以使用ExecuteFunction()ExecuteFunctionWithContext()方法执行JS函数,并通过回调机制实现异步通信。

2、Q: CEF3中如何创建和使用JS基本数据类型?

A: CEF3支持创建JS基本数据类型,包括undefined, null, bool, int, double, date和string,这些类型使用CefV8Value::Create*()静态方法创建,创建一个新的JS string类型使用CreateString()方法。

到此,以上就是小编对于“cef3 c js”的问题就介绍到这了,希望介绍的几点解答对大家有用,有任何问题和不懂的,欢迎各位朋友在评论区讨论,给我留言。

原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1378553.html

本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。

(0)
未希新媒体运营
上一篇 2024-12-04 23:22
下一篇 2024-04-24 01:54

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

产品购买 QQ咨询 微信咨询 SEO优化
分享本页
返回顶部
云产品限时秒杀。精选云产品高防服务器,20M大带宽限量抢购 >>点击进入