Google Test 学习笔记(简称GTest)

文章目录

  • 一、介绍
    • 1.1 介绍
    • 1.2 教程
  • 二、使用
    • 2.1 基本使用
      • 2.1.1 安装GTest (下载和编译)
      • 2.1.2 编写测试
      • 2.1.3 运行测试
      • 2.1.4 高级特性
      • 2.1.5 调试和分析
    • 2.2 源码自带测试用例
    • 2.3 TEST 使用
      • 2.3.1 TestCase的介绍
      • 2.3.2 TEST宏
        • demo1
        • demo2
      • 2.3.3 TEST_F宏
      • 2.3.4 TEST 和 TEST_IF 区别
    • 2.4 EXPECT_*和ASSERT_*的宏介绍
      • 2.4.1 gtest之断言
      • 2.4.2 Boolean断言类型
      • 2.4.3 二元值断言类型
      • 2.4.4 字符串断言类型
  • 三、参考资料
  • 四、其他内容
    • 4.1 gtest 和 C++ 版本

一、介绍

1.1 介绍

Google Test(通常简称GTest)是Google开发的一个用于C++的单元测试框架,它可以帮助你轻松地编写和运行测试用例,确保代码的质量和稳定性。

  • 最大好处:实现自动化单元测试

1.2 教程

  • 官网:https://google.github.io/googletest/
  • 源码:https://github.com/google/googletest
  • 参考:gtest教程(记录小白从0学习gtest的过程)
  • GoogleTest测试框架介绍(二)
  • C++ 的测试框架之使用 gtest 编写单元测试

二、使用

  1. 编译库
  2. 编写工程代码
  3. 编写测试用例代码
  4. 工程:
    • 工程源码:库 / 程序
    • samples:示例程序,演示如何使用库的基本功能。
    • test:gtest

2.1 基本使用

2.1.1 安装GTest (下载和编译)

1.下载源码:
访问Google Test GitHub仓库,下载或克隆源码。

2.编译GTest:
GTest可以通过CMake等构建工具来构建。以CMake为例,你需要创建一个构建目录,然后运行CMake和Make工具。

mkdir build
cd build
cmake ..
make

3.安装GTest:
将GTest的库文件和头文件复制到你的项目中,或者在你的构建系统中链接GTest库。

2.1.2 编写测试

1.包含GTest头文件:
在你的测试文件中,需要包含GTest的头文件。

#include "gtest/gtest.h"

2.定义测试用例和测试函数:
测试用例(TEST_F)通常对应于一组相关的测试函数,而测试函数(TEST)则是具体执行的测试逻辑。

TEST(FactorialTest, PositiveNumbers) {  // 单独的测试函数EXPECT_EQ(1, Factorial(0));EXPECT_EQ(1, Factorial(1));EXPECT_EQ(2, Factorial(2));EXPECT_EQ(6, Factorial(3));
}class MyMathTest : public ::testing::Test {
protected:void SetUp() override {// 初始化工作}
};TEST_F(MyMathTest, TestAddition) {EXPECT_EQ(5, Add(2, 3));
}

3.断言:
使用GTest提供的断言来检查函数的行为是否符合预期。例如,EXPECT_EQ用于比较两个值是否相等。

4.测试驱动:
在main函数中调用::testing::InitGoogleTest和RUN_ALL_TESTS来初始化GTest并运行所有的测试。

int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

2.1.3 运行测试

1.编译测试:
使用你的构建系统(如Makefile或CMakeLists.txt)来编译你的测试代码。

2.执行测试:
运行生成的可执行文件来执行测试。GTest会输出测试的结果,包括通过、失败或跳过的测试。

2.1.4 高级特性

  • 参数化测试:使用INSTANTIATE_TEST_SUITE_P来创建一系列使用不同参数的测试用例。
  • 死亡测试:使用ASSERT_DEATH或EXPECT_DEATH来检查代码是否会在特定条件下崩溃。
  • Google Mock:GTest的一部分,用于创建和使用mock对象来进行更复杂的测试。

2.1.5 调试和分析

  • 测试过滤:在运行测试时,可以使用–gtest_filter参数来指定运行哪些测试。
  • 测试日志:使用–gtest_output=xml:test_results.xml等选项来生成测试报告。

2.2 源码自带测试用例

  • 参考:https://gitcode.csdn.net/65acab6ab8e5f01e1e451947.html

我们还没有添加我们自己的源码,和针对源码的测试用例,但是谷歌已经写好了一些例子,可以先体验下,放在如下路径:/xxx/googletest-1.15.0/googletest

测试:

  1. 修改 CMakeLists.txt

    # 这里 OFF 改成 ON
    option(gtest_build_samples "Build gtest's sample programs." OFF)
    

    相关编译内容:

    if (gtest_build_samples)cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)cxx_executable(sample3_unittest samples gtest_main)cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)cxx_executable(sample6_unittest samples gtest_main)cxx_executable(sample7_unittest samples gtest_main)cxx_executable(sample8_unittest samples gtest_main)cxx_executable(sample9_unittest samples gtest)cxx_executable(sample10_unittest samples gtest)
    endif()
    
  2. 编译:

    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=pwd/result -DGOOGLETEST_VERSION=1.5.0 ..
    make -j4# 单个文件编译
    # g++ ../src/gtest_main.cc sample1.cc sample1_unittest.cc -o test -lgtest -lgmock -lpthread -std=c++11
    
  3. 运行:

    ./sample1_unittest 
    

    输出:在这里插入图片描述

  4. 理解:

    • gtest_main.cc :测试主程序入口,不是我们待测源码的主程序入口。

      情况一:整个工程有两个main函数,一个是测试的main,一个可能是待测源码的main,两个包含main的文件不能同时编译,因为一个执行程序只能有一个入口。(可以n个文件n个main函数)

      情况二:一个main函数通过宏定义区分启动

    • sample1.cc:待测源码,就是测试对象,我们就是要对个源码进行白盒测试。
    • sample1_unittest.cc:测试用例,里面就是我们针对源码写的测试用例脚本。
  5. 工程:

    • 工程源码:库 / 程序
    • samples:示例程序,演示如何使用库的基本功能。
    • test:gtest
  6. 遗留问题:编译没看懂—>再看

2.3 TEST 使用

  • 转自:Gtest入门2 Gtest之TEST宏的用法

2.3.1 TestCase的介绍

Gtest提供了若干个case方法进行测试不同的用例。主要常见的有TEST/TEST_F及TEST_P宏的使用。

在每个TestCase中可以通过断言提供的方法进行控制检查程序的预期走向是否是期望的结果,从而以此来判定程序的正确性。

在同一份TestCase中不能同时出现TEST和TEST_F两者进行混用;

其次TEST_F比TEST强的地方是会通过继承::testing::Test生成一个新类,而且这是必须的。

在新类中可以通过void SetUp();和void TearDown();进行创建和清除相关的资源数据;

2.3.2 TEST宏

TEST宏的作用是创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用提供的断言来进行检查。

TEST语法定义:
TEST(test_case_name, test_name)
  • test_case_name第一个参数是测试用例名,通常是取测试函数名或者测试类名
  • test_name 第二个参数是测试名这个随便取,但最好取有意义的名称
  • 当测试完成后显示的测试结果将以"测试用例名.测试名"的形式给出
demo1
// test.cpp
// g++ -std=c++14 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread
#include <iostream>
#include <memory>
#include <gtest/gtest.h>using namespace std;class Base {
public:Base(std::string name):m_name{name} {std::cout << "name: " << m_name << std::endl;}std::string getName() {return m_name;}~Base() {std::cout << "destory base" << std::endl;}
private:std::string m_name;
};void getNameFunc(std::shared_ptr<Base> base) {std::cout << __func__ << " : usercount: " << base.use_count() << std::endl;std::cout << __func__ << " : name: " << base->getName() << std::endl;// EXPECT_EQ(2, base.use_count());
}TEST(Base, createInstance) {std::unique_ptr<Base> instance = make_unique<Base>("SvenBaseUnique");// 测试创建的instance实例是否不为nullptrEXPECT_NE(instance, nullptr);instance.reset();// 测试instance实例是否为nullptrEXPECT_EQ(instance, nullptr);
}TEST(Base, getName) {std::unique_ptr<Base> instance = make_unique<Base>("BaseUnique");EXPECT_NE(instance, nullptr);auto name = instance->getName();// 测试获取的name值是否和被给的值相等EXPECT_STREQ(name.c_str(), "BaseUnique");instance.reset();EXPECT_EQ(instance, nullptr);
}TEST(Base, shared_ptr) {std::shared_ptr<Base> instance = std::make_shared<Base>("BaseShared");EXPECT_NE(instance, nullptr);std::cout << "shared_ptr.use_count: " << instance.use_count() << std::endl;// 测试instance引用次数是否为1EXPECT_EQ(1, instance.use_count());getNameFunc(instance);EXPECT_EQ(1, instance.use_count());
}TEST(Base, unique_ptr) {std::unique_ptr<Base> instance = make_unique<Base>("BaseUnique");EXPECT_NE(instance, nullptr);getNameFunc(std::move(instance));EXPECT_EQ(instance, nullptr);
}
demo2
// test_2.cc
// g++ -std=c++14  test_2.cc -o test_2 -I../../include -L ../lib -lgtest -lpthread
#include <gtest/gtest.h>
#include <vector>
#include <string>
#include <cmath>// 示例函数,用于测试
int Add(int a, int b) {return a + b;
}std::vector<int> GetPrimesUnder100() {std::vector<int> primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};return primes;
}class StringClass {
public:std::string Reverse(const std::string& s) {return std::string(s.rbegin(), s.rend());}
};// 测试类
class MyTest : public ::testing::Test {
protected:StringClass stringObj;
};// 测试用例:测试 Add 函数
TEST(AdditionTest, HandlesZeroInput) {EXPECT_EQ(Add(0, 0), 0);ASSERT_EQ(Add(0, 1), 1);// EXPECT_EQ(Add(0, 0), 30);   // error test// ASSERT_EQ(Add(0, 1), 30);// ASSERT_EQ(Add(1, 1), 2);
}TEST(AdditionTest, HandlesPositiveInput) {EXPECT_EQ(Add(2, 3), 5);ASSERT_EQ(Add(-1, 1), 0);
}TEST(AdditionTest, HandlesNegativeInput) {EXPECT_EQ(Add(-1, -1), -2);ASSERT_EQ(Add(-2, 3), 1);
}// 测试用例:测试 GetPrimesUnder100 函数
TEST(PrimeTest, ReturnsCorrectPrimes) {auto primes = GetPrimesUnder100();ASSERT_EQ(primes.size(), 25);EXPECT_EQ(primes[0], 2);EXPECT_EQ(primes[24], 97);
}// 测试用例:测试 StringClass 的 Reverse 方法
TEST_F(MyTest, ReversesString) {std::string original = "hello";std::string reversed = stringObj.Reverse(original);EXPECT_EQ(reversed, "olleh");
}TEST_F(MyTest, ReversesEmptyString) {std::string original = "";std::string reversed = stringObj.Reverse(original);EXPECT_EQ(reversed, "");
}TEST_F(MyTest, ReversesSingleCharacterString) {std::string original = "a";std::string reversed = stringObj.Reverse(original);EXPECT_EQ(reversed, "a");
}// 测试用例:测试浮点数比较
TEST(FloatTest, ComparesFloats) {float a = 1.0f + 1e-5f;float b = 1.0f;EXPECT_NEAR(a, b, 1e-4f);
}// 测试用例:测试布尔值
TEST(BooleanTest, ChecksTrue) {bool condition = true;EXPECT_TRUE(condition);ASSERT_TRUE(condition);
}TEST(BooleanTest, ChecksFalse) {bool condition = false;EXPECT_FALSE(condition);ASSERT_FALSE(condition);
}// 测试用例:测试异常
TEST(ExceptionTest, ThrowsException) {ASSERT_THROW(throw std::runtime_error("test exception"), std::runtime_error);
}// 测试用例:测试子测试
TEST(SubtestTest, Subtest1) {SUCCEED() << "This is a subtest.";EXPECT_EQ(1, 1);
}TEST(SubtestTest, Subtest2) {SUCCEED() << "This is another subtest.";EXPECT_EQ(2, 2);
}int main(int argc, char **argv) {::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

2.3.3 TEST_F宏

TEST_F主要是进行多样测试,就是多种不同情况的测试TestCase中都会使用相同一份的测试数据的时候将会才用它。
即用相同的数据测试不同的行为,如果采用TEST宏进行测试那么将会为不同的测试case创建一份数据。TEST_F宏将会共用一份避免重复拷贝共具灵活性。

语法定义为:
TEST_F(test_case_name, test_name);
  • test_case_name第一个参数是测试用例名,必须取类名。这个和TEST宏不同
  • test_name 第二个参数是测试名这个随便取,但最好取有意义的名称
  • 使用TEST_F时必须继承::testing::Test类。并且该类提供了两个接口void SetUp(); void TearDown();
    void SetUp()函数,为测试准备对象.
    void TearDown()函数 为测试后销毁对象资源
    

2.3.4 TEST 和 TEST_IF 区别

在 Google Test 中,TESTTEST_F 是用来定义测试用例的两个不同的宏。它们之间的主要区别在于是否需要测试夹具(test fixture):

  1. TEST(SuiteName, TestName)

    • TEST 宏用于定义不需要特殊初始化或清理的简单测试用例。
    • 它不接受任何参数,因此也不需要测试夹具类。
    • 测试用例函数是自动实例化的,并且每个测试用例都是独立的,不共享任何设置。
    • 适用于快速、独立的测试,不需要重复的初始化逻辑。

    示例代码:

    TEST(MultiplicationTest, HandlesZero) {EXPECT_EQ(0 * 5, 0);
    }
    
  2. TEST_F(TestFixture, TestName)

    • TEST_F 宏用于定义需要使用测试夹具的测试用例。
    • 测试夹具是一个从 ::testing::Test 派生的类,你可以在里面定义公共和受保护的成员,这些成员在每个测试用例中都可以访问。
    • 测试夹具类允许你在 SetUp 方法中编写初始化代码,这些代码会在每个测试用例运行之前执行,而在 TearDown 方法中编写清理代码,这些代码会在每个测试用例运行之后执行。
    • 适用于需要共享初始化逻辑和成员数据的测试用例。

    示例代码:

    class MultiplicationTest : public ::testing::Test {
    protected:int result;void SetUp() override {result = 0;}void TearDown() override {// 清理工作,如果需要的话}
    };TEST_F(MultiplicationTest, HandlesZero) {result = 0 * 5;EXPECT_EQ(result, 0);
    }
    

除了 TESTTEST_F,Google Test 还有一个宏 TEST_P,它用于定义参数化测试。参数化测试允许你用不同的参数多次运行同一个测试用例。

关于 TEST_IF 宏,实际上 Google Test 标准库中并没有这个宏。可能你指的是 TEST_P 或者某个特定版本的 Google Test 中的宏,或者是第三方扩展。通常情况下,TEST_P 用于参数化测试,允许你为测试用例提供参数,并且可以结合 INSTANTIATE_TEST_CASE_P 宏来实例化多个测试用例。

如果你需要更具体的信息或者有特定的使用场景,请提供更多的上下文,我可以给出更准确的答案。

2.4 EXPECT_*和ASSERT_*的宏介绍

  • 转自:Gtest入门2 Gtest之TEST宏的用法

2.4.1 gtest之断言

要测试一个类或函数,我们需要对其行为做出断言。当一个断言失败时,Google Test会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在Google Test的错误信息之后。

断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。

  • ASSERT_*版本的断言失败时会产生致命失败,并结束当前函数。
  • EXPECT_*版本的断言产生非致命失败,而不会中止当前函数。

通常更推荐使用EXPECT_*断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用ASSERT_*断言。 因为失败的ASSERT_*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。

gtest中断言的宏可以分为两类:一类是ASSERT宏,另一类就是EXPECT宏了。
1、ASSERT_*系列:如果当前点检测失败则退出当前函数
2、EXPECT_*系列:如果当前点检测失败则继续往下执行

2.4.2 Boolean断言类型

在这里插入图片描述

2.4.3 二元值断言类型

比较两个值的大小。
在这里插入图片描述

2.4.4 字符串断言类型

比较两个字符串。
在这里插入图片描述

三、参考资料

  • 玩转C++单元测试之快速上手gtest

  • Google Test(GTEST)使用入门(1)- 下载编译安装执行

四、其他内容

4.1 gtest 和 C++ 版本

Google Test(GTest)对不同版本的 C++ 标准的支持有所变化。下面是 Google Test 对 C++ 标准版本支持的大致时间线和相关信息。

Google Test 对 C++ 标准的支持

  • GTest 1.8.1(发布于 2015 年 7 月 29 日):

    • 支持 C++98、C++03、C++11、C++14。
    • 从 GTest 1.8.1 开始,GTest 支持 C++14,并且开始逐渐移除对旧版本 C++ 标准的支持。
  • GTest 1.10.0(发布于 2019 年 10 月 28 日):

    • 支持 C++11、C++14、C++17。
    • GTest 1.10.0 版本开始正式移除对 C++98 和 C++03 的支持。
  • GTest 1.11.0(发布于 2021 年 1 月 25 日):

    • 支持 C++11、C++14、C++17。
    • GTest 1.11.0 版本继续支持 C++11、C++14 和 C++17。
  • GTest 1.12.1(发布于 2022 年 8 月 17 日):

    • 支持 C++11、C++14、C++17、C++20。
    • GTest 1.12.1 版本增加了对 C++20 的支持。
  • GTest 1.13.0(发布于 2023 年 11 月 2 日):

    • 支持 C++14、C++17、C++20。
    • GTest 1.13.0 版本移除了对 C++11 的支持,现在仅支持 C++14 及以上版本。

总结

  • 最新版本(截至 2024 年 7 月 25 日):

    • GTest 1.13.0 支持 C++14、C++17 和 C++20。
  • 历史版本

    • GTest 1.12.1 支持 C++11、C++14、C++17 和 C++20。
    • GTest 1.11.0 支持 C++11、C++14 和 C++17。
    • GTest 1.10.0 支持 C++11、C++14 和 C++17。
    • GTest 1.8.1 支持 C++98、C++03、C++11 和 C++14。

建议

  • 使用最新版本

    • 如果您的项目可以使用较新的 C++ 版本,建议使用 GTest 1.13.0 或更高版本,以获得更好的特性和支持。
    • 对于 C++14 及以上版本的支持,您可以使用 GTest 1.13.0。
  • 使用较旧版本

    • 如果您的项目受限于旧版本的 C++,您可以考虑使用相应的 GTest 版本。例如,如果您的项目使用 C++11,您可以考虑使用 GTest 1.12.1 或更低版本。

示例编译命令

如果您使用的是 GTest 1.13.0 或更高版本,并且您的编译器支持 C++14 或更高版本,您可以使用以下编译命令:

g++ -std=c++14 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread

请确保您的编译器支持所需的 C++ 标准版本。如果您的编译器不支持 C++14 或更高版本,您可能需要升级编译器或考虑使用较低版本的 GTest。

如果您需要使用 C++11,您可以使用 GTest 1.12.1 或更低版本,并相应地更新编译命令中的 C++ 标准版本:

g++ -std=c++11 ../../src/gtest_main.cc test.cpp -o test -I../../include -L ../lib -lgtest -lpthread

请根据您的具体需求调整编译命令中的 C++ 标准版本。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SOC 芯片设计 DFT 学习专栏 -- DFT OCC 与 ATPG的介绍】

请阅读【嵌入式及芯片开发学必备专栏】 请阅读【芯片设计 DFT 学习系列 】 如有侵权&#xff0c;请联系删除 转自&#xff1a; 简矽芯学堂 简矽芯学堂 2024年01月18日 09:00 陕西 文章目录 OCC 介绍Fast ScanFull chip ATPGPartition ATPGHierarchical ATPG OCC 介绍 OCC&am…

反激Flyback从逆向到初步设计(UC2844)

一.Flyback基本拓扑 国标gb/t 12325-2008《电能质量供电电压偏差》规定&#xff1a;220v单向供电电压偏差为标称电压的-10%&#xff0c;7%。 对应220V的标称电压&#xff0c;其浮动范围是在198~235.4V。以下运算均基于此规定进行。 首先220V进入EMI模块&#xff0c;消除差模干扰…

SSRF学习笔记

1.NAT学习 Nat&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是 一种网络通信技术主要用于将私有网络中的内部IP地址转换成公共网络中的公共IP地址&#xff0c;以实现局域网内部设备访问互联网的功能。具体来说&#xff0c;Nat有以下几个主要…

redis的学习

! 快速入门 安装 1.使用docker安装redis docker pull redisdocker run -d --name redis -p 6379:6379 --restart unless-stopped -v /etc/docker/Redis/data:/data -v /etc/docker/Redis/conf/redis.conf:/usr/local/etc/redis/redis.conf redis redis-server /usr/local/e…

小白也能读懂的ConvLSTM!(开源pytorch代码)

ConvLSTM 1. 算法简介与应用场景2. 算法原理2.1 LSTM基础2.2 ConvLSTM原理2.2.1 ConvLSTM的结构2.2.2 卷积操作的优点 2.3 LSTM与ConvLSTM的对比分析2.4 ConvLSTM的应用 3. PyTorch代码参考文献 仅需要网络源码的可以直接跳到末尾即可 1. 算法简介与应用场景 ConvLSTM&#x…

【漏洞复现】phpStudy 小皮 Windows面板 存在RCE漏洞

靶场资料后台自行领取【靶场】 image-20240726092307252 PhpStudy小皮面板曝RCE漏洞&#xff0c;本质是存储型XSS引发。攻击者通过登录用户名输入XSS代码&#xff0c;结合后台计划任务功能&#xff0c;实现远程代码执行&#xff0c;严重威胁服务器安全。建议立即更新至安全版…

OpenSSL SSL_connect: Connection was reset in connection to github.com:443

OpenSSL SSL_connect: Connection was reset in connection to github.com:443 目录 OpenSSL SSL_connect: Connection was reset in connection to github.com:443 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&…

机器视觉12-相机

相机 作用: 工业相机 是 机器视觉系统 的重要组成部分 最本质的功能就是通过CCD或CMOS成 像传感器将镜头产生的光信号转变为 有序的电信号&#xff0c;并将这些信息通过相 应接口传送到计算机主机 工业相机分类 目前业内没有对相机进行明确的分类定义&#xff0c; 以下分类是…

正点原子 通用外设配置模型 GPIO配置步骤 NVIC配置

1. 这个是通用外设驱动模式配置 除了初始化是必须的 其他不是必须的 2. gpio配置步骤 1.使能时钟是相当于开电 2.设置工作模式是配置是输出还是输入 是上拉输入还是下拉输入还是浮空 是高速度还是低速度这些 3 和 4小点就是读写io口的状态了 3. 这个图是正点原子 将GPIO 的时…

鸿蒙开发—黑马云音乐之Music页面

目录 1.外层容器效果 2.信息区-发光效果 3.信息区-内容布局 4.播放列表布局 5.播放列表动态化 6.模拟器运行并配置权限 效果&#xff1a; 1.外层容器效果 Entry Component export struct MuiscPage {build() {Column() {// 信息区域Column() {}.width(100%)// .backgroun…

带有扰动观测器的MPC电机控制

模型预测控制(Model Predictive Contro1, MPC)是一种先进的控制策略&#xff0c;虽然具有鲁棒性、建模简单、处理多变量系统、显示约束、预测未来行为和优化性能的能力等优势。它的不足在于预测控制行为的计算需要繁琐的计算量&#xff0c;以及抗干扰能力较弱。这里提出基于扰动…

GPIO子系统

1. GPIO子系统视频概述 1.1 GPIO子系统的作用 芯片内部有很多引脚&#xff0c;这些引脚可以接到GPIO模块&#xff0c;也可以接到I2C等模块。 通过Pinctrl子系统来选择引脚的功能(mux function)、配置引脚&#xff1a; 当一个引脚被复用为GPIO功能时&#xff0c;我们可以去设…

数组模拟单调栈--C++

本题的计算量较大&#xff0c;用暴力算法会超时&#xff0c;的用别的方法&#xff0c;我们假设在左边找第一个比它小的数&#xff0c;那么在左边出现一次的数如果比右边大了&#xff0c;那么就不会在出现了&#xff0c;我们将它删除掉就可以了&#xff0c;用这个方法我们可以的…

28.Labview界面设计(上篇) --- 软件登陆界面设计与控件美化

摘要&#xff1a; 作为GUI界面设计的老大哥般的存在&#xff0c;Labview本身的G语言属性就展现了其优越的外观设计能力&#xff0c;其中不乏许多编程爱好者、架构师等的喜欢使用Labview进行界面相关的设计&#xff0c;而使用Matlab、Python等软件写底层数据处理模块、自动化脚本…

Javaweb项目|springboot医院管理系统

收藏点赞不迷路 关注作者有好处 文末获取源码 一、系统展示 二、万字文档展示 基于springboot医院管理系统 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringSpringMVCMyBatisVue 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 编号&#xff1a;…

通信原理-思科实验五:家庭终端以太网接入Internet实验

实验五 家庭终端以太网接入Internet实验 一实验内容 二实验目的 三实验原理 四实验步骤 1.按照上图选择对应的设备&#xff0c;并连接起来 为路由器R0两个端口配置IP 为路由器R1端口配置IP 为路由器设备增加RIP&#xff0c;配置接入互联网的IP的动态路由项 5.为路由器R1配置静…

如何使用Firefox浏览器连接IPXProxy设置海外代理IP教程

​Firefox浏览器是大家上网时经常会使用的一款工具。不过&#xff0c;有时候我们会遇到一些网站无法直接访问的情况。这时候&#xff0c;通过海外代理IP&#xff0c;比如像IPXProxy代理这样的服务&#xff0c;可能就能帮助我们进入那些受限制的网站&#xff0c;获取我们所需的资…

手写spring简易版本,让你更好理解spring源码

首先我们要模拟spring&#xff0c;先搞配置文件&#xff0c;并配置bean 创建我们需要的类&#xff0c;beandefito&#xff0c;这个类是用来装解析后的bean&#xff0c;主要三个字段&#xff0c;id&#xff0c;class&#xff0c;scop&#xff0c;对应xml配置的属性 package org…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第六十三章 输入子系统实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

IP 泄露: 原因与避免方法

始终关注您的IP信息&#xff01; 您的IP地址不仅显示您的位置&#xff0c;它包含几乎所有的互联网活动信息&#xff01; 如果出现IP泄漏&#xff0c;几乎所有的信息都会被捕获甚至非法利用&#xff01; 那么&#xff0c;网站究竟如何追踪您的IP地址&#xff1f;您又如何有效…