Application Structure

应用程序结构

Every CEF3 application has the same general structure.

  • Provide an entry-point function that initializes CEF and runs either sub-process executable logic or the CEF message loop.
  • Provide an implementation of CefApp to handle process-specific callbacks.
  • Provide an implementation of CefClient to handle browser-instance-specific callbacks.
  • Call CefBrowserHost::CreateBrowser() to create a browser instance and manage the browser life span using CefLifeSpanHandler.

每个CEF3应用程序都是相同的结构

  • 提供入口函数,用于初始化CEF、运行子进程执行逻辑或者CEF消息循环。
  • 提供CefApp实现,用于处理进程相关的回调。
  • 提供CefClient实现,用于处理browser实例相关的回调
  • 执行CefBrowserHost::CreateBrowser()创建一个browser实例,使用CefLifeSpanHandler管理browser对象生命周期。
Entry-Point Function
入口函数

As described in the “Processes” section a CEF3 application will run multiple processes. The processes can all use the same executable or a separate executable can be specified for the sub-processes. Execution of the process begins in the entry-point function. Complete platform-specific examples for Windows, Linux and Mac OS-X are available in cefclient_win.cc, cefclient_gtk.cc and cefclient_mac.mm respectively.

像本文中进程章节描述的那样,一个CEF3应用程序会运行多个进程,这些进程能够使用同一个执行器或者为子进程定制的、单独的执行器。进程的执行从入口函数开始,示例cefclient_win.cc、cefclient_gtk.cc、cefclient_mac.mm分别对应Windows、Linux和Mac OS-X平台下的实现。

When launching sub-processes CEF will specify configuration information using the command-line that must be passed into the CefExecuteProcess function via the CefMainArgs structure. The definition of CefMainArgs is platform-specific. On Linux and Mac OS X it accepts the argc and argv values which are passed into the main() function.

当执行子进程是,CEF将使用命令行参数指定配置信息,这些命令行参数必须通过CefMainArgs结构体传入到CefExecuteProcess函数。CefMainArgs的定义与平台相关,在Linux、Mac OS X平台下,它接收main函数传入的argc和argv参数值。

  1. CefMainArgs main_args(argc, argv);

On Windows it accepts the instance handle (HINSTANCE) which is passed into the wWinMain() function. The instance handle is also retrievable via GetModuleHandle(NULL).

在Windows平台下,它接收wWinMain函数传入的参数:实例句柄(HINSTANCE),这个实例能够通过函数GetModuleHandle(NULL)获取。

  1. CefMainArgs main_args(hInstance);
Single Executable
单个执行器

When running as a single executable the entry-point function is required to differentiate between the different process types. The single executable structure is supported on Windows and Linux but not on Mac OS X.

当运行单个执行器时,根据不同的进程类型,入口函数有差异。Windows、Linux平台支持单个执行器架构,Mac OS X平台则不行。

  1. // 程序执行函数
  2. int main(int argc, char* argv[]) {
  3. // Structure for passing command-line arguments.
  4. // The definition of this structure is platform-specific.
  5. // 传递命令行参数的结构体。
  6. // 这个结构体的定义与平台相关。
  7. CefMainArgs main_args(argc, argv);
  8. // Optional implementation of the CefApp interface.
  9. // 可选择地实现CefApp接口
  10. CefRefPtr<MyApp> app(new MyApp);
  11. // Execute the sub-process logic, if any. This will either return immediately for the browser
  12. // process or block until the sub-process should exit.
  13. // 可能会执行子进程逻辑,这个函数的执行在browser进程时会立即返回,在子进程时会堵塞直到退出时返回。
  14. int exit_code = CefExecuteProcess(main_args, app.get());
  15. if (exit_code >= 0) {
  16. // The sub-process terminated, exit now.
  17. // 子进程被终结,立即结束。
  18. return exit_code;
  19. }
  20. // Populate this structure to customize CEF behavior.
  21. // 填充这个结构体,用于定制CEF的行为。
  22. CefSettings settings;
  23. // Initialize CEF in the main process.
  24. // 在main进程中初始化CEF
  25. CefInitialize(main_args, settings, app.get());
  26. // Run the CEF message loop. This will block until CefQuitMessageLoop() is called.
  27. // 执行消息循环,此时会堵塞,直到CefQuitMessageLoop()函数被调用。
  28. CefRunMessageLoop();
  29. // Shut down CEF.
  30. // 退出CEF。
  31. CefShutdown();
  32. return 0;
  33. }
Separate Sub-Process Executable
单独子进程执行器

When using a separate sub-process executable you need two separate executable projects and two separate entry-point functions.

当使用一个单独子进程执行器时,你需要2个分开的可执行工程和2个分开的入口函数。

Main application entry-point function:

主程序的入口函数:

  1. // Program entry-point function.
  2. // 程序入口函数
  3. int main(int argc, char* argv[]) {
  4. // Structure for passing command-line arguments.
  5. // The definition of this structure is platform-specific.
  6. // 传递命令行参数的结构体。
  7. // 这个结构体的定义与平台相关。
  8. CefMainArgs main_args(argc, argv);
  9. // Optional implementation of the CefApp interface.
  10. // 可选择性地实现CefApp接口
  11. CefRefPtr<MyApp> app(new MyApp);
  12. // Populate this structure to customize CEF behavior.
  13. // 填充这个结构体,用于定制CEF的行为。
  14. CefSettings settings;
  15. // Specify the path for the sub-process executable.
  16. // 指定子进程的执行路径
  17. CefString(&settings.browser_subprocess_path).FromASCII(“/path/to/subprocess”);
  18. // Initialize CEF in the main process.
  19. // 在主进程中初始化CEF
  20. CefInitialize(main_args, settings, app.get());
  21. // Run the CEF message loop. This will block until CefQuitMessageLoop() is called.
  22. // 执行消息循环,此时会堵塞,直到CefQuitMessageLoop()函数被调用。
  23. CefRunMessageLoop();
  24. // Shut down CEF.
  25. // 关闭CEF
  26. CefShutdown();
  27. return 0;
  28. }

Sub-process application entry-point function: 子进程程序的入口函数:

  1. // Program entry-point function.
  2. // 程序入口函数
  3. int main(int argc, char* argv[]) {
  4. // Structure for passing command-line arguments.
  5. // The definition of this structure is platform-specific.
  6. // 传递命令行参数的结构体。
  7. // 这个结构体的定义与平台相关。
  8. CefMainArgs main_args(argc, argv);
  9. // Optional implementation of the CefApp interface.
  10. // 可选择性地实现CefApp接口
  11. CefRefPtr<MyApp> app(new MyApp);
  12. // Execute the sub-process logic. This will block until the sub-process should exit.
  13. // 执行子进程逻辑,此时会堵塞直到子进程退出。
  14. return CefExecuteProcess(main_args, app.get());
  15. }
Message Loop Integration
集成消息循环

CEF can also integrate with an existing application message loop instead of running its own message loop. There are two ways to do this.

CEF可以不用它自己提供的消息循环,而与已经存在的程序中消息环境集成在一起,有两种方式可以做到:

  1. Call CefDoMessageLoopWork() on a regular basis instead of calling CefRunMessageLoop(). Each call to CefDoMessageLoopWork() will perform a single iteration of the CEF message loop. Caution should be used with this approach. Calling the method too infrequently will starve the CEF message loop and negatively impact browser performance. Calling the method too frequently will negatively impact CPU usage.
  2. Set CefSettings.multi_threaded_message_loop = true (Windows only). This will cause CEF to run the browser UI thread on a separate thread from the main application thread. With this approach neither CefDoMessageLoopWork() nor CefRunMessageLoop() need to be called. CefInitialize() and CefShutdown() should still be called on the main application thread. You will need to provide your own mechanism for communicating with the main application thread (see for example the message window usage in cefclient_win.cpp). You can test this mode in cefclient on Windows by running with the “--multi-threaded-message-loop” command-line flag.

  3. 周期性执行CefDoMessageLoopWork()函数,替代调用CefRunMessageLoop()。CefDoMessageLoopWork()的每一次调用,都将执行一次CEF消息循环的单次迭代。需要注意的是,此方法调用次数太少时,CEF消息循环会饿死,将极大的影响browser的性能,调用次数太频繁又将影响CPU使用率。

  4. 设置CefSettings.multi_threaded_message_loop=true(Windows平台下有效),这个设置项将导致CEF运行browser UI运行在单独的线程上,而不是在主线程上,这种场景下CefDoMessageLoopWork()或者CefRunMessageLoop()都不需要调用,CefInitialze()、CefShutdown()仍然在主线程中调用。你需要提供主程序线程通信的机制(查看cefclient_win.cpp中提供的消息窗口实例)。在Windows平台下,你可以通过命令行参数“--multi-threaded-message-loop”测试上述消息模型。
CefSettings
CefSettings

The CefSettings structure allows configuration of application-wide CEF settings. Some commonly configured members include:

CefSettings结构体允许定义全局的CEF配置,经常用到的配置项如下:

  • single_process Set to true to use a single process for the browser and renderer. Also configurable using the "single-process" command-line switch. See the “Processes” section for more information.
  • browser_subprocess_path The path to a separate executable that will be launched for sub-processes. See the “Separate Sub-Process Executable” section for more information.
  • multi_threaded_message_loop Set to true to have the browser process message loop run in a separate thread. See the “Message Loop Integration” section for more information.
  • command_line_args_disabled Set to true to disable configuration of browser process features using standard CEF and Chromium command-line arguments. See the “Command Line Arguments” section for more information.
  • cache_path The location where cache data will be stored on disk. If empty an in-memory cache will be used for some features and a temporary disk cache will be used for others. HTML5 databases such as localStorage will only persist across sessions if a cache path is specified.
  • locale The locale string that will be passed to Blink. If empty the default locale of "en-US" will be used. This value is ignored on Linux where locale is determined using environment variable parsing with the precedence order: LANGUAGE, LC_ALL, LC_MESSAGES and LANG. Also configurable using the "lang" command-line switch.
  • log_file The directory and file name to use for the debug log. If empty, the default name of "debug.log" will be used and the file will be written to the application directory. Also configurable using the "log-file" command-line switch.
  • log_severity The log severity. Only messages of this severity level or higher will be logged. Also configurable using the "log-severity" command-line switch with a value of "verbose", "info", "warning", "error", "error-report" or "disable".
  • resources_dir_path The fully qualified path for the resources directory. If this value is empty the cef.pak and/or devtools_resources.pak files must be located in the module directory on Windows/Linux or the app bundle Resources directory on Mac OS X. Also configurable using the "resources-dir-path" command-line switch.
  • locales_dir_path The fully qualified path for the locales directory. If this value is empty the locales directory must be located in the module directory. This value is ignored on Mac OS X where pack files are always loaded from the app bundle Resources directory. Also configurable using the "locales-dir-path" command-line switch.
  • remote_debugging_port Set to a value between 1024 and 65535 to enable remote debugging on the specified port. For example, if 8080 is specified the remote debugging URL will be http://localhost:8080. CEF can be remotely debugged from any CEF or Chrome browser window. Also configurable using the "remote-debugging-port" command-line switch.

  • single_process 设置为true时,browser和renderer使用一个进程。此项也可以通过命令行参数“single-process”配置。查看本文中“进程”章节获取更多的信息。

  • browser_subprocess_path 设置用于启动子进程单独执行器的路径。参考本文中“单独子进程执行器”章节获取更多的信息。
  • cache_path 设置磁盘上用于存放缓存数据的位置。如果此项为空,某些功能将使用内存缓存,多数功能将使用临时的磁盘缓存。形如本地存储的HTML5数据库只能在设置了缓存路径才能跨session存储。
  • locale 此设置项将传递给Blink。如果此项为空,将使用默认值“en-US”。在Linux平台下此项被忽略,使用环境变量中的值,解析的依次顺序为:LANGUAE,LC_ALL,LC_MESSAGES和LANG。此项也可以通过命令行参数“lang”配置。
  • log_file 此项设置的文件夹和文件名将用于输出debug日志。如果此项为空,默认的日志文件名为debug.log,位于应用程序所在的目录。此项也可以通过命令参数“log-file”配置。
  • log_severity 此项设置日志级别。只有此等级、或者比此等级高的日志的才会被记录。此项可以通过命令行参数“log-severity”配置,可以设置的值为“verbose”,“info”,“warning”,“error”,“error-report”,“disable”
  • resources_dir_path 此项设置资源文件夹的位置。如果此项为空,Windows平台下cef.pak、Linux平台下devtools_resourcs.pak、Mac OS X下的app bundle Resources目录必须位于组件目录。此项也可以通过命令行参数“resource-dir-path”配置。
  • locales_dir_path 此项设置locale文件夹位置。如果此项为空,locale文件夹必须位于组件目录,在Mac OS X平台下此项被忽略,pak文件从app bundle Resources目录。此项也可以通过命令行参数“locales-dir-path”配置。
  • remote_debugging_port 此项可以设置1024-65535之间的值,用于在指定端口开启远程调试。例如,如果设置的值为8080,远程调试的URL为http://localhost:8080。CEF或者Chrome浏览器能够调试CEF。此项也可以通过命令行参数“remote-debugging-port”配置。

Cef应用程序结构的更多相关文章

  1. 谈谈.net模块依赖关系及程序结构

    技术为解决问题而生. 上面这个命题并非本文重点,我将来有空再谈这个.本文也并非什么了不起的技术创新,只是分享一下我对.net模块依赖关系及程序结构方面的一些看法.先看一个最最简单的hello worl ...

  2. 【C语言入门教程】1.1 基本程序结构

    基本程序结构就是从上至下顺序执行的程序,C语言程序必须有且只有一个主函数,程序从主函数开始执行,直到主函数结束.下例是根据半径求圆形面积的程序源代码. #include <stdio.h> ...

  3. C++程序结构---1

    C++ 基础教程Beta 版 原作:Juan Soulié 翻译:Jing Xu (aqua) 英文原版 本教程根据Juan Soulie的英文版C++教程翻译并改编. 本版为最新校对版,尚未定稿.如 ...

  4. ASP.NET MVC掉过的坑_MVC初识及MVC应用程序结构

    APS.Net MVC 浅谈[转] 来自MSDN 点击访问 MVC 理论结构 模型-视图-控制器 (MVC) 体系结构模式将应用程序分成三个主要组件:模型.视图和控制器. ASP.NET MVC 框架 ...

  5. MFC单文档程序结构

    MFC单文档程序结构三方面: Doc MainFrame View

  6. ecshop在线手册前言及程序结构

    该在线手册是有模版堂转载而来:仅供参考 一.前言 为什么我们ecshop模板堂要重制ecshop在线手册呢?因为目前网上的一些教程有些是比较老的,有些是不全面的,官方的手册也已经很久没有更 新,很多刚 ...

  7. C语言之程序结构

    一个好的程序首先要有好的程序结构,我从变量和结构两个方面来做分析. 一.浅谈程序中的变量 一个程序架构最基本的就是程序变量,谈到程序中的变量,我们应该考虑两部分,一方面是变量的作用域,一方面是变量的生 ...

  8. C#学习笔记二:C#程序结构

    从最简单的HelloWorld开始入手,这是一个最低限度的C#程序结构. C# Hello World 示例 一个C#程序主要由以下几部分组成: 命名空间声明 一个类 类方法 类属性 一个Main方法 ...

  9. Windows 应用程序结构

    Windows 应用程序结构

随机推荐

  1. C语言结构体初始化的四种方法(转载)

    原文:https://blog.csdn.net/ericbar/article/details/79567108 定义 struct InitMember { int first: double s ...

  2. CodeForces - 899E Segments Removal (优先队列 + 链表)

    给定一个序列,每次从序列中找一个长度最大的元素相同的片段,删除它. 如果长度相同,删除最靠左边的那个片段. 问,需要删几次. 用链表处理删除片段.对于删除之后两边又能连成一个片段的那种情况,用set记 ...

  3. HUD:2853-Assignment(KM算法+hash)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2853 Assignment Time Limit: 2000/1000 MS (Java/Others) ...

  4. 对java多线程的一些浅浅的理解

    作为一名JAVA初学者,前几天刚刚接触多线程这个东西,有了些微微的理解想写下来(不对的地方请多多包涵并指教哈). 多线程怎么写代码就不说了,一搜一大堆.说说多线程我认为最难搞的地方,就是来回释放锁以及 ...

  5. 2.新手必须掌握的Linux命令

    第2章 新手必须掌握的Linux命令 章节简述: 本章首先介绍系统内核和Shell终端的关系与作用,然后介绍Bash解释器的4大优势并学习Linux命令的执行方法.经验丰富的运维人员可以通过合理地组合 ...

  6. 大数据学习——SparkStreaming整合Kafka完成网站点击流实时统计

    1.安装并配置zk 2.安装并配置Kafka 3.启动zk 4.启动Kafka 5.创建topic [root@mini3 kafka]# bin/kafka-console-producer. -- ...

  7. 03-python进阶-爬虫入门-正则

    [urllib and urllib2] 这是两个python的网络模块 内置的 提供很好的网络访问的功能. #!coding:utf-8 import urllib2 res = urllib2.u ...

  8. 触屏版轻量级分页插件jqPagination分享

    说到HTML5和jquery上的分页问题,优秀的分页插件网上一抓一大把,然而同时适合兼容在Ipad和手机端的网站分页却不是特别多. 或许有人会说,触屏现在流行下拉底部后加载下一页内容,类似微博和QQ空 ...

  9. 字符串匹配之Sunday算法

    Sunday算法不像KMP算法那么复杂,但是效率又比较高,在KMP之上,下面简单介绍Sunday算法及其实现. Sunday 算法由 Daniel M.Sunday 在 1990 年提出,它的思想跟 ...

  10. P1108 低价购买 (动态规划)

    题目链接 Solution 似乎就是个很简单的最长不上升子序列输出方案. 但是有一个很艹蛋的条件: 不同方案选择价格必须不同. 且其股票价格不保证不相同. \(f[i]\) 代表以第 \(i\) 天结 ...