WebRTC-Streamer交叉编译
WebRTC-Streamer交叉编译
flyfish
文章目录
- WebRTC-Streamer交叉编译
- 零、前言
- 一、提前准备工作
- 1 安装需要的工具
- 2 可选的交叉编译工具
- 3 默认执行python是python3
- 4 获取源码
- 5 使用其他版本的方法
- 二、非交叉编译编译
- 1 在 src目录执行 安装所需的依赖
- 2 执行命令
- 三、 交叉编译
- 1 独立使用的方法,无需提供给WebRTC-Streamer使用的方法
- 2 提供给WebRTC-Streamer使用的方法
- 四、开始编译WebRTC-Streamer
- 五、以下是不同版本的编译,可能出现的错误和解决方案
- 问题1缺少rtmp
- 问题 2 链接问题
- 问题3 live555helper
- 问题4 WebRTC和WebRTC-Streamer两者版本,其中之一过旧或者过新问题
- 问题5 未安装工具的错误
- 问题6 编译工具与代码版本问题
- 问题7 使用clang或者gcc不同编译器编译的情况
零、前言
WebRTC-Streamer源码
https://github.com/mpromonet/webrtc-streamer
官网给的三步是
1安装 Chromium depot tools
pushd ..
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:`realpath depot_tools`
popd
2 下载 WebRTC
mkdir ../webrtc
pushd ../webrtc
fetch --no-history webrtc
popd
3 构建 WebRTC Streamer
cmake . && make
这里实践第三步首先要编译WebRTC,然后再编译WebRTC-Streamer
webrtc编译
一、提前准备工作
1 安装需要的工具
sudo apt-get install build-essential pkg-config devhelp glade libglade2-dev
sudo apt-get install libgtk-3-dev
sudo apt install ninja-build
sudo apt install git
sudo apt install libcanberra-gtk-module
sudo apt install cmake
sudo apt install python3-pip
pip3 install dataclasses
2 可选的交叉编译工具
https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/
3 默认执行python是python3
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3 /usr/bin/python
python --version
4 获取源码
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
创建webrtc文件夹
终端命令进入webrtc文件夹后,执行命令
加载路径
export PATH=/path/to/depot_tools:$PATH
替换成depot_tools所在路径,这里用的是
export PATH="$PATH:/home/a/source/depot_tools/"
fetch --nohooks webrtc
gclient sync
5 使用其他版本的方法
切换到分支方法
查看有哪些版本
https://webrtc.github.io/webrtc-org/release-notes/


打开链接可以看到M85 和4183
进入 webrtc/src目录,执行命令
git checkout -b m85 branch-heads/4183
gclient sync
或者通过git branch -r 查看有哪些分支
二、非交叉编译编译
可编译x86_64版本
1 在 src目录执行 安装所需的依赖
./build/install-build-deps.sh
这里实际用的是
./build/install-build-deps.sh --no-chromeos-fonts #跳过字体的安装
2 执行命令
gn gen out/Default --args='is_debug=false'
ninja -C out/Default
三、 交叉编译
可编译arm32或者arm64版本
根据自己需要选择
1 独立使用的方法,无需提供给WebRTC-Streamer使用的方法
如果是要交叉编译,需要执行
./build/linux/sysroot_scripts/install-sysroot.py --arch=arm #32位
./build/linux/sysroot_scripts/install-sysroot.py --arch=arm64 #64位
普通的交叉编译
第一步
gn gen out/linux_arm --args='target_os="linux" target_cpu="arm" use_custom_libcxx=false' #32位
gn gen out/linux_arm64 --args='target_os="linux" target_cpu="arm64" use_custom_libcxx=false' #64位
第二步
ninja -C out/linux_arm #32位
ninja -C out/linux_arm64 #64位
2 提供给WebRTC-Streamer使用的方法
交叉编译命令
还可以是如下命令
假如是arm32下
第一步
gn gen out/Release --args=‘rtc_use_x11=false rtc_use_pipewire=false is_clang=true use_sysroot=false target_cpu=“arm” is_chrome_branded=true is_debug=false use_custom_libcxx=false rtc_include_tests=false rtc_enable_protobuf=false rtc_build_examples=false rtc_build_tools=false treat_warnings_as_errors=false rtc_enable_libevent=false rtc_build_libevent=false use_ozone=true rtc_build_json=true’
第二步
ninja -C out/Release webrtc rtc_json jsoncpp builtin_video_decoder_factory builtin_video_encoder_factory peerconnection p2p_server_utils task_queue default_task_queue_factory
四、开始编译WebRTC-Streamer
以arm32为例
cmake -DCMAKE_SYSTEM_PROCESSOR=armv7l -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_C_COMPILER=/home/a/tool/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -DCMAKE_CXX_COMPILER=/home/a/tool/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY -DWEBRTCOZONE=Yes -DWEBRTCDESKTOPCAPTURE=OFF .
以上编译命令类似
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)set(tools /home/a/tool/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
可选的
set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(CMAKE_STAGING_PREFIX /home/devel/stage)
如果不想写这么长的工具路径,可以如下操作

usr/local/下建立一个arm32文件夹,将工具拷贝进去
编辑~/.bashrc加上一句
export PATH=$PATH:/usr/local/arm32/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
五、以下是不同版本的编译,可能出现的错误和解决方案
问题1缺少rtmp
In file included from /home/a/source/webrtc-streamer/inc/CapturerFactory.h:34,from /home/a/source/webrtc-streamer/src/PeerConnectionManager.cpp:26:
/home/a/source/webrtc-streamer/inc/rtmpvideosource.h:32:10: 致命错误: librtmp/rtmp.h:没有那个文件或目录#include <librtmp/rtmp.h>^~~~~~~~~~~~~~~~
编译中断。
CMakeFiles/webrt
方式1:
下载
http://rtmpdump.mplayerhq.hu/download/
rtmpdump-2.3
放置到
librtmp
/home/a/source/webrtc-streamer/inc/librtmp
然后再解决链接问题
arm-linux-gnueabihf/bin/ld: cannot find -lrtmp
arm-linux-gnueabihf/bin/ld: cannot find -lz
arm-linux-gnueabihf/bin/ld: cannot find -lgmp
方式2
不使用rtmp
更改CMakeList.txt
# rtmp ?
# find_package(PkgConfig QUIET)
# pkg_check_modules(RTMP QUIET librtmp)
# MESSAGE("RTMP_FOUND = ${RTMP_FOUND}")
# if (RTMP_FOUND)
# add_definitions(-DHAVE_RTMP)
# target_link_libraries (${CMAKE_PROJECT_NAME} ${RTMP_LIBRARIES})
# endif()
问题 2 链接问题
arm-linux-gnueabihf/bin/ld: cannot find -lX11
arm-linux-gnueabihf/bin/ld: cannot find -lXext
arm-linux-gnueabihf/bin/ld: cannot find -lXdamage
arm-linux-gnueabihf/bin/ld: cannot find -lXfixes
arm-linux-gnueabihf/bin/ld: cannot find -lXcomposite
arm-linux-gnueabihf/bin/ld: cannot find -lXrandr
arm-linux-gnueabihf/bin/ld: cannot find -lXtst
通过查看CMakeLists.txt x11需要 X11 Xext Xdamage Xfixes Xcomposite Xrandr Xtst
if (EXISTS ${WEBRTCROOT}/src/out/${CMAKE_BUILD_TYPE}/obj/modules/desktop_capture/desktop_capture.ninja)add_definitions(-DUSE_X11)target_link_libraries (${CMAKE_PROJECT_NAME} X11 Xext Xdamage Xfixes Xcomposite Xrandr Xtst)endif()
简单的方法就是除去 x11 dep
webrtc增加参数
gn gen out/Release --args增加参数 use_ozone=true rtc_use_x11=false
webrtc-streamer的编译增加参数
cmake -DCMAKE_SYSTEM_PROCESSOR=armv7l -DWEBRTCOZONE=Yes -DWEBRTCDESKTOPCAPTURE=OFF .
问题3 live555helper
错误提示
struct std::atomic_flag’ has no member named ‘test’
详细的是
/home/a/source/webrtc-streamer/live/BasicUsageEnvironment/BasicTaskScheduler.cpp: 在成员函数‘virtual void BasicTaskScheduler::SingleStep(unsigned int)’中:
/home/a/source/webrtc-streamer/live/BasicUsageEnvironment/BasicTaskScheduler.cpp:191:40: 错误: ‘struct std::atomic_flag’ has no member named ‘test’if (fTriggersAwaitingHandling[i].test()) {^~~~
live555helper/CMakeFiles/liblive555helper.dir/build.make:89: recipe for target 'live555helper/CMakeFiles/liblive555helper.dir/__/live/BasicUsageEnvironment/BasicTaskScheduler.cpp.o' failed
make[2]: *** [live555helper/CMakeFiles/liblive555helper.dir/__/live/BasicUsageEnvironment/BasicTaskScheduler.cpp.o] Error 1
make[2]: *** 正在等待未完成的任务....
解决方法
增加NO_STD_LIB=1 或者 -DNO_STD_LIB
可以根据自己所需的系统更改
编译最后更改如下
if (WIN32)target_compile_definitions(liblive555helper PUBLIC _CRT_SECURE_NO_WARNINGS=1 NO_GETIFADDRS=1)target_link_libraries (liblive555helper ws2_32)
elseif (APPLE)target_compile_definitions(liblive555helper PUBLIC BSD=1 SOCKLEN_T=socklen_t _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 NEED_XLOCALE_H=1)
else ()target_compile_definitions(liblive555helper PUBLIC BSD=1 SOCKLEN_T=socklen_t _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 NO_STD_LIB=1)
endif()
问题4 WebRTC和WebRTC-Streamer两者版本,其中之一过旧或者过新问题
示例1
:208:18: 错误: ‘class rtc::Thread’ has no member named ‘Invoke’m_workerThread->Invoke<void>(RTC_FROM_HERE, [this, audioLayer] {^~~~~~
:208:25: 错误: expected primary-expression before ‘void’m_workerThread->Invoke<void>(RTC_FROM_HERE, [this, audioLayer] {^~~~
:210:6: 错误: expected primary-expression before ‘)’ token});^
: 在析构函数‘virtual PeerConnectionManager::~PeerConnectionManager()’中:
:340:18: 错误: ‘class rtc::Thread’ has no member named ‘Invoke’m_workerThread->Invoke<void>(RTC_FROM_HERE, [this] {^~~~~~
:340:25: 错误: expected primary-expression before ‘void’m_workerThread->Invoke<void>(RTC_FROM_HERE, [this] {^~~~
:342:6: 错误: expected primary-expression before ‘)’ token
示例2
../../modules/audio_processing/agc2/adaptive_digital_gain_controller_unittest.cc:107:41: error: no member named 'log10f' in namespace 'std'; did you mean simply 'log10f'?107 | const float applied_gain_db = 20.0f * std::log10f(applied_gain);| ^~~~~~~~~~~| log10f
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/arm-linux-gnueabihf/bits/mathcalls.h:107:1: note: 'log10f' declared here107 | __MATHCALL (log10,, (_Mdouble_ __x));| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:273:3: note: expanded from macro '__MATHCALL'273 | __MATHDECL (_Mdouble_,function,suffix, args)| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:275:3: note: expanded from macro '__MATHDECL'275 | __MATHDECL_1(type, function,suffix, args); \| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:283:15: note: expanded from macro '__MATHDECL_1'283 | extern type __MATH_PRECNAME(function,suffix) args __THROW| ^
../../build/linux/debian_bullseye_armhf-sysroot/usr/include/math.h:303:34: note: expanded from macro '__MATH_PRECNAME'303 | # define __MATH_PRECNAME(name,r) name##f##r| ^
<scratch space>:211:1: note: expanded from here211 | log10f| ^
1 error generated.
问题5 未安装工具的错误
例如
pkg-config
ERROR at //build/config/linux/pkg_config.gni:104:17: Script returned non-zero exit code.pkgresult = exec_script(pkg_config_script, args, "json")^----------
Current dir: /home/a/source/webrtc/src/out/linux_arm/
Command: python3 /home/a/source/webrtc/src/build/config/linux/pkg-config.py -s /home/a/source/webrtc/src/build/linux/debian_bullseye_armhf-sysroot -a arm gmodule-2.0 gthread-2.0 gtk+-3.0
Returned 1.
stderr:Traceback (most recent call last):File "/home/a/source/webrtc/src/build/config/linux/pkg-config.py", line 247, in <module>sys.exit(main())File "/home/a/source/webrtc/src/build/config/linux/pkg-config.py", line 142, in mainprefix = GetPkgConfigPrefixToStrip(options, args)File "/home/a/source/webrtc/src/build/config/linux/pkg-config.py", line 81, in GetPkgConfigPrefixToStrip"--variable=prefix"] + args, env=os.environ).decode('utf-8')File "/usr/lib/python3.6/subprocess.py", line 356, in check_output**kwargs).stdoutFile "/usr/lib/python3.6/subprocess.py", line 423, in runwith Popen(*popenargs, **kwargs) as process:File "/usr/lib/python3.6/subprocess.py", line 729, in __init__restore_signals, start_new_session)File "/usr/lib/python3.6/subprocess.py", line 1364, in _execute_childraise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'pkg-config': 'pkg-config'See //examples/BUILD.gn:665:5: whence it was called.pkg_config("gtk_config") {^-------------------------
See //BUILD.gn:42:17: which caused the file to be included.deps += [ "examples" ]
dataclasses
ninja -C out/linux_arm
ninja: Entering directory `out/linux_arm'
[122/6960] ACTION //experiments:regist...der(//build/toolchain/linux:clang_arm)
FAILED: gen/experiments/registered_field_trials.h
python3 ../../experiments/field_trials.py header --output gen/experiments/registered_field_trials.h
Traceback (most recent call last):File "../../experiments/field_trials.py", line 15, in <module>import dataclasses
ModuleNotFoundError: No module named 'dataclasses'
[131/6960] CXX obj/logging/fake_rtc_event_log/fake_rtc_event_log.o
ninja: build stopped: subcommand failed.
问题6 编译工具与代码版本问题
例如webrtc使用旧代码时,gn版本过高导致的错误
降低gn版本
:~/source/webrtc/src$ gn gen out/Default
ERROR at //build/config/BUILDCONFIG.gn:401:1: Unknown function.
set_sources_assignment_filter(sources_assignment_filter)
gn --version
2119 (cc56a0f98bb3)
问题7 使用clang或者gcc不同编译器编译的情况

LLVM: clang / clang++(https://clang.llvm.org/)
GNU: gcc / g++( https://gcc.gnu.org/)
同样 的编译参数-std=c++17在默认的情况下,是用了不同的标准库
g++ with libstdc++ (by default)
clang++ with libc++ (by default)
在使用gcc编译的情况下,使用系统级别的函数时ibstdc++会调用glibc,Host上的gcc如果使用的glibc过高,到了Target就运行不起来
参考
https://webrtc.org.cn/mirror/
https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API
相关文章:
WebRTC-Streamer交叉编译
WebRTC-Streamer交叉编译 flyfish 文章目录 WebRTC-Streamer交叉编译零、前言一、提前准备工作1 安装需要的工具2 可选的交叉编译工具3 默认执行python是python34 获取源码5 使用其他版本的方法 二、非交叉编译编译1 在 src目录执行 安装所需的依赖2 执行命令 三、 交叉编译1 …...
将目录下的所有pdf文件都转换为对应名字的png图片
本来想用Foxit来把pdf转换为png,但没想到是收费的功能,所以在参考1处找了一段python代码,稍作修改实现了这个功能。做个记录后续可能有用。 在python3.9.12上运行代码遇到了版本的坑,好几个坑,最终发现只要安装这个特…...
windows主机和Ubuntu虚拟机共享设置
参考文章 Ubuntu Linux 与主机共享文件夹 vim 修改文件出现错误 “ E45: ‘readonly’ option is set (add to override)“ vim退出时报错“E212: Cant open file for writing”的解决办法 VMware 安装后,安装Ubuntu 20.04一路顺利。 1,在VMware设置…...
北京APP外包开发需要注意的问题
开发APP的过程中,由于开发APP需要投入大量的时间、精力和资源,所以在开始前一定要做好充足的准备和规划。您需要注意以下重点,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1…...
自然语言处理:提取长文本进行文本主要内容(文本意思)概括 (两种方法,但效果都一般)
本文主要针对长文本进行文本提取和中心思想概括,原文档放在了附件里面:<科大讯飞公告> -----------------------------------方法一:jieba分词提取文本(句子赋分法)------------------------- 1、首先导入相关…...
基于SpringCloudAlibaba实现的NacosConfig
概述 Nacos除了实现了服务的注册发现之外,还将配置中心功能整合在了一起。通过Nacos的配置管理功能,我们可以将整个架构体系内的所有配置都集中在Nacos中存储。这样做的好处主要有以下几点: 分离的多环境配置,可以更灵活的管理权…...
景联文科技:高质量AI数据标注助力大语言模型训练,推动人工智能落地应用
大语言模型在各类LLM新技术的融会贯通下,不断加速Instruction-tuning、RLHF、思维链等新技术在大语言模型中的深度应用,人工智能技术以惊人的速度不断进化。 大语言模型(LLM)是一种基于深度学习技术和海量文本数据,它们…...
深度学习(前馈神经网络)知识点总结
用于个人知识点回顾,非详细教程 1.梯度下降 前向传播 特征输入—>线性函数—>激活函数—>输出 反向传播 根据损失函数反向传播,计算梯度更新参数 2.激活函数(activate function) 什么是激活函数? 在神经网络前向传播中&#x…...
点云从入门到精通技术详解100篇-点云信息编码(中)
目录 2.4.3 基于预测树结构的几何信息压缩算法 2.5 点云属性信息编码技术...
前端刷题-Promise系列
Promise系列 promise.all // 定义 Promise.all function (promises) {let count 0;let result [];return new Promise((resolve, reject) > {for (let i 0; i < promises.length; i) {promises[i].then((res) > {count;result[i] res;if (count promises.leng…...
3分钟:腾讯云免费SSL证书申请教程_免费HTTPS证书50张
2023腾讯云免费SSL证书申请流程,一个腾讯云账号可以申请50张免费SSL证书,免费SSL证书为DV证书,仅支持单一域名,申请腾讯云免费SSL证书3分钟即可申请成功,免费SSL证书品牌为TrustAsia亚洲诚信,腾讯云百科分享…...
如何快速成为一名优秀的python工程师?
随着人工智能的发展与应用,Python编程语言受到世界各界人士的关注,Python工程师也成为一个热门职业,就业薪资高,发展前景广阔。 Python是一门简单的编程语言,学习相对更加轻松容易,初学者很容易入门&#…...
Sqoop(二):Hive导出数据到Oracle
把Hive中的数据导入Oracle数据库。 1. 解释一下各行代码: sqoop export # 指定要从Hive中导出的表 --table TABLE_NAME # host_ip:导入oracle库所在的ip:导入的数据库 --connect jdbc:oracle:thin:HOST_IP:DATABASE_NAME # oracle用户账号 --username USERNAM…...
HTML数字倒计时效果附源码
HTML页面代码 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content...
以udp协议创建通信服务器
概念图 创建服务器让A,B主机完成通信。 认识接口 socket 返回值:套接字,你可以认为类似fd 参数: domain->:哪种套接字,常用AF_INET(网络套接字)、AF_LOCAL(本地套接字)type->:发送数据类型,常用 …...
【数据结构】队列篇| 超清晰图解和详解:循环队列模拟、用栈实现队列、用队列实现栈
博主简介:努力学习的22级计算机科学与技术本科生一枚🌸博主主页: 是瑶瑶子啦每日一言🌼: 每一个不曾起舞的日子,都是对生命的辜负。——尼采 目录 一、 模拟实现循环队列二、用栈实现队列⭐三、225. 用队列实现栈 一、…...
js+html实现打字游戏v2
实现逻辑,看jshtml实现打字游戏v1,在此基础之上增加了从文件读取到的单词,随机选取10个单词。 效果演示 上代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&l…...
Python之作业(一)
Python之作业(一) 作业 打印九九乘法表 用户登录验证 用户依次输入用户名和密码,然后提交验证用户不存在、密码错误,都显示用户名或密码错误提示错误3次,则退出程序验证成功则显示登录信息 九九乘法表 代码分析 先…...
uni-app 之 v-on:click点击事件
uni-app 之 v-on:click点击事件 image.png <template><!-- vue2的<template>里必须要有一个盒子,不能有两个,这里的盒子就是 view--><view>--- v-on:click点击事件 ---<view v-on:click"onclick">{{title}}<…...
迁移学习:实现快速训练和泛化的新方法
文章目录 迁移学习的原理迁移学习的应用快速训练泛化能力提升 迁移学习的代码示例拓展应用与挑战结论 🎉欢迎来到AIGC人工智能专栏~迁移学习:实现快速训练和泛化的新方法 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页:IT陈寒的博…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
