如何在C++ QT 程序中集成cef3浏览器组件去显示网页?

news2024/11/17 8:26:54

目录

1、问题描述

2、为什么选择cef3浏览器组件

3、cef3组件的介绍与下载

4、将cef3组件封装成sdk

5、如何使用cef3组件加载web页面

5.1、了解CefApp与CefClient

5.2、初始化与消息循环

5.3、如何创建浏览器

5.4、重载CefClient类

6、在qt客户端集成cef组件

7、最后


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(专栏文章已更新400多篇,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlWindows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html       本文讲述如何在C++ QT客户端程序中集成基于Chrome内核的浏览器组件cef3,主要用于在客户端程序中显示Web网页。

1、问题描述

       我们的qt客户端软件需要引入一个内嵌浏览器控件去显示一个Web页面,即在客户端程序中去打开某个Web网页。鉴于Chromium内核的稳定性,这个内嵌的浏览器控件决定使用Google开源的基于Chromium内核的浏览器组件cef3来实现,本文主要讲述如何在qt客户端软件中集成cef3组件。

2、为什么选择cef3浏览器组件

       如何在qt客户端中加载显示web网页,主要有两种方式:

1)使用系统自带的浏览器

启动操作系统上安装的浏览器并打开指定的web网页,此方案实现简单,不需要客户端做复杂的逻辑处理,但是受系统上安装的浏览器影响。此外,系统浏览器和客户端程序是相互独立的,没有关联性,用户体验不太好。

2)在程序中内嵌浏览器控件

直接在客户端上内嵌浏览器控件,使用该控件去打开web页面,此方式有多种技术可以实现。可以使用qt自带的组件和第三方组件等,此方式比较灵活,也可以让用户体验更好些,但是会对现有客户端代码产生一定影响。

       根据我们自身项目的特点,以及对多个技术方案的调研,整理了一下,如下所示:

经讨论,最终决定使用内嵌cef3浏览器组件的方案。

3、cef3组件的介绍与下载

      cef(Chromium Embedded Framework)是基于谷歌Chromium内核开发的框架,让开发者能够以更简单的方式使用Chromium内核开发基于网页的程序,cef3是当前维护中的版本,cef1和cef2已停止维护。cef3有多种语言的版本,包括主流的c、c++、java、python、c#等,且支持多种主流操作系统,包括windows、linux、mac os等。由于我们客户端项目是使用qt框架开发的win32版本的c++客户端,所以本案例也将使用win32下的c++版本的cef3进行介绍。

       可以到官网上去下载:

https://bitbucket.org/chromiumembedded/cef

下载压缩包并解压后,将看到一些目录,各个目录的内容如下:

cmake目录:包含cmake编译脚本。
Debug和Release目录:存放着已经编译好的cef3库文件以及运行时文件,包括dll、lib等。除了lib文件是编译时使用外,其它文件都是cef3运行时用到的文件,注意不要遗漏,否则程序可能会启动失败。
include目录:包含c接口的头文件。
libcef_dll目录:包含c++接口的头文件及其源码(cef3的c++接口是基于c接口封装的,如果想使用c++接口则需要自行编译libcef_dll目录下的源码,如果只使用c接口则直接使用include下接口就可以了。这里面还包含了一些测试代码,可手动删除)。
Resources目录:资源目录,包含cef3运行时需要使用到的资源文件。注意不要遗漏,否则程序可能会启动失败。
tests目录:包含示例代码。

4、将cef3组件封装成sdk

        实际在调研时就发现cef3组件无法直接与我们的qt-mingw版本的客户端代码一起编译(应该和cef3的交叉编译有关,即不能在windows上使用mingw的gnu编译器编译)。可以用Visual Studio(VS2008)对cef3进行一次封装并生成sdk,将生成的sdk集成进qt客户端就没问题了。

        有人可能会问,为啥不把我们的qt-mingw版本换成qt-vc++的版本呢?其实,在一开始调研时,为了方便确实是想使用此策略的,但是很快就发现了个很大的问题:由于我们qt客户端项目经过多年的迭代(包括很多代码是新人所写),导致直接将现有qt-mingw版本切换到qt-vc++版本将面临很大的改动。基于时间成本以及维护成本的考虑,先将cef3封装成sdk再集成进现有qt客户端的方案将是更有利的。

        当然,使用VS2008及其之后的版本对cef3进行封装都是可以的,这里主要考虑到我们现有客户端项目已经使用了VS2008封装的其它sdk,这样我们就可以使用同一套VC++版本的库了。本案例使用的是cef3的C++接口,在封装成sdk时也一同将C++接口的源码编译进来了,在编译C++接口的源码时有几个地方需要注意下:

1)cef3使用了c99标准头文件stdint.h,vc++2008是没有这个头文件的,需要自己额外添加此文件。vc++2008之后的版本是包含这个头文件的。
2)标准库std::min/std::max与windows头文件中的min/max宏冲突问题,这个只需要在预处理器配置中添加NOMINMAX宏即可。


       在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:(该精品技术专栏的订阅量已达到510多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)

C++软件调试与异常排查从入门到精通系列文章汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2:  

C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795

常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!

专栏3:(本专栏涵盖了多方面的内容,是当前重点打造的专栏,专栏文章已经更新到400多篇,持续更新中...)

C/C++实战进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。

专栏4:   

VC++常用功能开发汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585

将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。

专栏5: 

Windows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.html

根据多年C++软件开发实践,详细地总结了Windows C++ 应用软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


5、如何使用cef3组件加载web页面

        本文因为篇幅,没法对cef3进行详细的讲解,可以看看官方的三个文档,对cef3有个基本了解:

https://bitbucket.org/chromiumembedded/cef/wiki/Tutorial.md
https://bitbucket.org/chromiumembedded/cef/wiki/Architecture.md
https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage.md

       要想使用cef3加载web,基本包含3个步骤:初始化cef3进程并启动cef3消息循环,利用cef3接口创建浏览器,使用创建好的浏览器加载web。

       根据cef3的架构理论,cef3会创建多个进程,其中主进程用于创建浏览器,进行浏览器界面的绘制等,也被称为浏览器进程(本案例中与qt客户端进程为同一进程)。其它进程为子进程,子进程包括用于web引擎渲染的渲染进程,加载诸于flash插件的插件进程,利用gpu进行加速的gpu进程。子进程由cef3内部自动创建,默认情况下主进程和子进程都是通过可执行程序创建的(也就是说qt客户端的main函数会被多次调用),可以通过配置指定子进程的可执行文件路径。

5.1、了解CefApp与CefClient

       正如前面所提到的,本案例使用的是cef3的C++接口,C++接口相较于c接口更易于使用。CefApp与CefClient是使用C++接口时需要理解的两个重要类。

       CefApp类用于处理与进程之间的交互,CefClient类用于处理与浏览器实例之间的交互。初始化cef3进程时可以指定CefApp实例,通过CefApp实例处理cef3进程的消息。创建浏览器时可以指定CefClient实例,通过CefClient实例处理浏览器的消息。

       对于cef3的C++接口,创建浏览器实例是一个异步操作,实际创建成功时需要通过CefClient实例进行通知,所以为了后续可以利用浏览器加载web,需要保存创建好的浏览器实例,这里可以对CefClient类就行重载,并在收到浏览器创建成功的通知时保存好实例。一个CefClient实例可以对应多个浏览器实例,为了容易实现对浏览器的一对一映射,本案例中每个浏览器实例在创建时都会指定一个新的CefClient实例,且在主程序中保存这些CefClient实例,并通过CefClient实例操作浏览器实例进行web加载等操作。

5.2、初始化与消息循环

       本文中使用的初始化流程如下:

cef3的初始化涉及到两个接口:CefExecuteProcess和CefInitialize:

1)CefExecuteProcess接口用于子进程的创建;

2)CefInitialize接口用于主进程的初始化。

       根据前面提到的cef3的架构理论,默认情况下主进程和子进程都是通过可执行程序创建,本案例中使用的是这种默认情况,即主进程的创建和子进程的创建都会调用qt客户端的main函数,然后在main函数里程序会调用CefSdkInit接口。这里可以通过CefExecuteProcess接口的返回值来判断当前进入的是主进程还是子进程:

  • 如果返回值小于0则表明进入的是主进程,这时程序会继续执行,并最终调用CefInitialize接口初始化主进程;
  • 如果返回值大于等于0则表明进入的是子进程,需要直接返回(如果进入的是主进程,CefExecuteProcess接口会立即返回,如果进入的是子进程,CefExecuteProcess接口会一直阻塞,直到子进程结束才返回)。

CefSdkInit的返回值是用来表明进入的是否是主进程,如果返回false则main函数应该立即返回。

       主进程在初始化时有个重要的参数需要设置:multi_threaded_message_loop,即是否使用多线程消息循环(1表示使用,0表示不使用,默认为1)。这里的设置会对后续程序的处理产生一些影响:

  • 如果选择使用多线程消息循环,则cef3内部会自动处理诸于鼠标、键盘等这种系统消息,以及一些内部消息,代价就是会造成,CefClient在处理浏览器消息通知时是在其它线程里的,和程序的主线程(本案例为客户端的界面线程)不在同一个线程。
  • 如果选择不使用多线程消息循环,则cef3内部不会主动触发对消息的处理,需要程序每隔一段时间调用一次CefDoMessageLoopWork接口,这里的难点在于多久调用一次CefDoMessageLoopWork接口比较合适,如果调用次数太频繁,造成不必要的性能浪费,如果调用次数太少,会导致cef3消息处理速度过慢,造成消息丢失或卡顿的现象(这里建议多尝试几个时间间隔,本案例中使用的是此种情况,时间间隔在10毫秒)。

5.3、如何创建浏览器

       本文中创建浏览器的接口如下:

这里可以看出,虽然本案例中提供了两套接口用于创建浏览器,实际创建浏览器调用的接口都是CefBrowserHost类的静态函数CreateBrowser,其返回值表明是否创建成功。根据CefWindwoInfo参数可以指定是创建一个独立的弹出窗口(CefSdkBrowserCreateAsPopup)还是创建一个内嵌的子窗口(CefSdkBrowserCreateAsChild)。

       CreateBrowser接口并不返回一个浏览器实例的句柄或指针啥的,真正对浏览器进行实例化的是在cef3内部进行的,等到浏览器被实例化后会通过CefClient的实例通知进来。这里的第二个参数用到的CCefSimpleClient类就是CefClient类的一个子类,本案例中每当需要创建一个浏览器实例时都会创建一个CCefSimpleClient类的实例,确保一一对应。

       在创建浏览器时会指定一个窗口句柄(windows下为HWND类型)参数,此句柄是作为浏览器窗口的父窗口句柄,不是浏览器窗口本身,cef3内部会自动创建一个新的窗口作为浏览器窗口,所以在创建浏览器时还可以指定新窗口的标题(winName)或矩形区域大小(width、height)。

5.4、重载CefClient类

       前面提到CefClient类是处理与浏览器之间的交互的,但是如果查看CefClient类的接口会发现,CefClient类本身并不直接处理与浏览器之间的消息,而是通过提供一套虚函数接口,这些接口可以创建一系列句柄类的实例,通过这些句柄类的实例再去处理相关消息。为了方便理解,这些句柄类都是类似于CefXXXHandler的形式。

        其中,CefLifeSpanHandler类就是可以处理浏览器创建成功的通知消息。鉴于cef3提供的此套接口,我们还需要对用到的CefXXXHandler类进行重载,本案例中为了实现方便,将同时从CefClient类和CefXXXHandler类继承,具体继承关系如下图所示:

所有的CefClient类接口和CefXXXHandler类接口都是虚函数接口,方便用户重载。

        当浏览器创建成功后,cef3会调用CefClient实例的GetLifeSpanHandler接口获取一个CefLifeSpanHandler实例,并调用其OnAfterCreated接口;同理当浏览器需要被销毁前会自动触发OnBeforeClose接口被调用。注意这里的OnBeforePopup接口不是在调用CefSdkBrowserCreateAsPopup(参见3.3.3节的介绍)接口创建浏览器后被调用的,而是web内部有弹出窗口时被调用(比如很多网页内部都有弹出广告等)。

       此外,CCefSimpleClient类还添加了一个CefBrowser类指针的一个成员变量。一个CefBrowser类实例代表的就是一个浏览器实例。本案例中会确保一个CefBrowser实例对应一个CCefSimpleClient实例,所以只需保存一个CefBrowser类实例的指针。在这里保存浏览器的实例方便后续加载web。自定义CCefSimpleClient类的具体实现如下图所示:

小提示:本案例中所提到的浏览器和实际我们平时使用的浏览器的概念是有所差异的,本案例中提到的浏览器的概念对应我们实际使用的浏览器的一个tab页。

6、在qt客户端集成cef组件

       本文中cef组件已经被封装成了sdk,本质上和其它sdk没有区别,集成方式也和其它sdk没有区别。这里将集成cef组件过程中发现的一些重要问题总结下。

       浏览器窗口大小缩放的问题。如果创建的是内嵌的浏览器窗口,由于浏览器窗口本身是由cef3内部创建的,qt客户端的大小在缩放时不会对浏览器窗口的大小进行缩放,这里就需要手动缩放。具体方式就是要找到对应浏览器窗口的句柄,然后调用系统函数进行缩放(win32下为MoveWindow函数)。本案例中在CefSimpleClient类中添加了一个Resize函数,如下图所示:

       浏览器窗口焦点和qt客户端窗口焦点冲突问题。也还是因为浏览器窗口是由cef3自己创建的这个原因,cef3创建的窗口不在qt系统管理范围内,所以会导致浏览器窗口和qt客户端窗口会同时获得焦点的情况,并导致某些异常问题。此问题的处理方式是在浏览器窗口获得焦点后通知qt系统。好在cef3已经为我们考虑到这个问题了,方法就是继承CefFocusHandler类,通过重载其OnGotFocus函数得知浏览器窗口什么时候会获得焦点。

       本案例中是让CefSimpleClient类同时继承了多个父类,其中就包括CefFocusHandler类。当程序得知浏览器窗口获得焦点后,简单点的方式就是触发下浏览器父类窗口(通常是某个QWidget实例)获得焦点就行了(setFocus(Qt::ActiveWindowFocusReason)),从使用者的角度来讲,浏览器父类窗口和浏览器窗口一般没有这种焦点冲突问题。

7、最后

       本文主要分享的是在qt客户端上集成cef3时遇到的一些问题的总结,没有包含很多比较详细的使用cef3的细节,有些问题也没有提及到,但是cef框架作为一个开源架构也行之有效多年,网上有很多相关的技术文章可以参考,网站下载的压缩包里也能看到一些例子。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2052727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VS2022上面运行QT程序

需求:之前是在QT6.6上面运行,现在想试一下VS2022: 操作步骤: 第一步: 在QT的配置软件中安装MSVC 第二步:配置VS 第三步:在VS上面安装QT插件,但是在QT上面安装速度很慢,…

Leetcode面试经典150题-15.三数之和

解法都在代码里,不懂就留言或者私信 class Solution {/**每次做这个题都想着这事最后一次了,但是确实很高频,还是多练练吧基本思路:先把原来的数组按照从小到大的顺序排列,然后我们从头开始确定第一个数,然…

STM32CubeMX stm32不限长度使用DMA收发串口数据

STM32CubeMX 配置 代码 stm32h7xx_it.c /*** brief This function handles UART7 global interrupt.*/ void UART7_IRQHandler(void) {/* USER CODE BEGIN UART7_IRQn 0 */if (UART7 huart7.Instance) // 判断是否是空闲中断{if (__HAL_UART_GET_FLAG(&huart7, UART_FLA…

数据导入导出(EasyExcel)框架入门指南

写在前面 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站 文章目录 EasyExcel 框架概述依赖APIExcel 实体类注解写 Excel概念介绍写 Excel 通用参数WriteWorkbookWriteSheetWriteTable 代码…

【Qt】常用控件QRadioButton

常用控件QRadioButton QRadioButton是单选按钮,可以在多个选项中选择一个。 作为QAbstractButton和QWidget的子类,其属性和用法,对于QRadioButton同样适用。 属性说明 checkable 是否能选中 checked 是否已经被选中. checkable 是 checked…

平安养老险宿州中支开展消防培训及逃生演练活动

近日,平安养老保险股份有限公司(以下简称“平安养老险”)宿州中心支公司邀请助安消防公司袁教官为公司员工开展消防安全知识培训。 培训教官结合近年来火灾典型案例,对火灾的危害、火灾的预防措施、灭火器材的使用进行深入浅出的…

centos 常用软件的安装和使用

redis 安装 0、下载、解压那些的我在这儿就不说了,有不懂的,看我之前写的博客。 1、在安装 redis 之前,我们得先安装它的依赖 yum install gcc-c 2、假设我下载放进的目录是 /usr/local/src/ , 并且 我的版本为 redis-6.0.8 …

数字化转型对金融服务业的影响

数字化转型正在塑造每个行业,从快速消费品到金融,每个行业都受到新兴技术的影响。 那么,数字化转型在金融服务中扮演什么角色?这对招聘前景有何影响? 我们探讨了数字化转型对该行业的影响、其对招聘策略的影响、数据…

适合大学生的耳机排行有哪些?四大TOP级性价比蓝牙耳机合集

大学生生活多彩多姿,耳机也成为了他们日常生活、学习和娱乐中不可或缺的配件。但面对市面上琳琅满目的耳机品牌和型号,选择性价比高且适合自身需求的耳机变得尤为重要,那么适合大学生的耳机排行有哪些?今天我就为大家精选了四大TO…

SpringBoot如何配置动态数据源?原理+实战

若没空探究原理可直接跳转到“实现方式&#xff1a;注解切面”目录 数据源切换方法 Spring对数据源的管理类似于策略模式&#xff0c;不懂策略模式也没关系&#xff0c;其实就是有一个全局的键值对&#xff0c;类型是Map<String, DataSource>。当JDBC操作数据库之时&am…

boot项目:程序包xxxx.xxxx.xxx不存在

你们好&#xff0c;我是金金金。 idea2021版本&#xff0c;在maven项目中运行程序的时候会出现java程序包不存在现象。(属于它的一个小bug) 场景 启动boot项目时报错如下 解决 清理缓存 重新加载所有maven项目 重新启动项目即可 测试 已测试&#xff0c;项目成功启动~ 编写有误…

代码规范 —— Redis 开发规范

优质博文&#xff1a;IT-BLOG-CN 一、开发规范 【1】弱依赖检查与线下确认&#xff1a;Redis必须是弱依赖&#xff0c;即Redis宕机不影响业务。包括超时检查。 【2】是否当存储使用检查&#xff1a;Redis不能作为存储设备来使用&#xff0c;只能作为缓存或状态等场景来使用。…

【Mudo库】实战项目之简要介绍

文章目录 前言一、效果演示二、模块1. 介绍2. 服务器模块3. 应用层模块 尾序 前言 各位C友们&#xff0c;好久不见&#xff0c;最近一个月在搞项目&#xff0c;算是半摆半学的状态吧&#xff0c;博客断更了一段时间&#xff0c;现在项目搞完了&#xff0c;博客之后也会慢慢更新…

机器学习周报(8.12-8.18)

文章目录 摘要Abstract1.Transformer的结构1.1 序列到序列&#xff08;Seq2seq&#xff09;的模型1.2 Transformer 结构1.2.1 Transformer 编码器&#xff08;Encoder&#xff09;1.2.2 Transformer解码器&#xff08;Decoder&#xff09;1.2.3 编码器-解码器注意力&#xff08…

Java语言程序设计——篇十四(2)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

c++11(二)

一、右值引用 1、区分左值和右值 语法定义&#xff0c;左值可以取地址&#xff0c;右值无法取地址&#xff08;右值肯定有地址&#xff0c;但是为了和左值区分&#xff0c;语法上不让取地址&#xff09; 左值&#xff1a;一个表示数据的表达式&#xff08;变量名或解引用指针…

如何配置ESXI主机的IP地址管理

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…

通过python脚本查询自己阿里云账号里的某个域名的A记录解析情况,以及测拨,用于排查未使用的解析

安装sdk pip install aliyun-python-sdk-alidns代码全文 import json import requests from aliyunsdkcore.client import AcsClient from aliyunsdkalidns.request.v20150109 import DescribeDomainRecordsRequest# 替换为你的阿里云 AccessKey ID 和 AccessKey Secret acce…

栈与队列 - 逆波兰表达式求值

150. 逆波兰表达式求值 方法一&#xff1a;栈 /*** param {string[]} tokens* return {number}*/ var evalRPN function(tokens) {const stack [];for (const token of tokens) {if (isNaN(Number(token))) { // 非数字const n2 stack.pop(); // 出栈两个数字const n1 s…

假期作业--数据结构

1、顺序表实现学生管理系统&#xff08;参照顺序表技能&#xff09;写出菜单界面switch选择&#xff0c;功能1创建顺序表&#xff08;堆区&#xff09;&#xff0c;2录入学生信息&#xff0c;3插入一个学生信息&#xff0c;4删除一个学生信息&#xff0c;5按照位置修改一个学生…