LwIP系列(1):C语言宏定义相关基础知识(##、include 文件、宏函数、预编译)

news2025/1/9 2:14:18

前言

对于嵌入式物联网技术来说,TCP/IP 协议几乎是不能绕过的,常见socket、tcp、udp、mqtt、coap、modbus-tcp、mdns、广播、组播等等,均是基于TCP/IP协议实现,无处不在。而目前在嵌入式领域,使用最多的TCP/IP协议栈就是LwIp,所以本系列尝试着从LwIP的详细分析,来入门学习TCP/IP协议。
在LwIP中,使用了很多高级的C语言用法,如果不了解这些高级用法,我们很难清楚的了解其实现原理,我们先从宏定义的高级用法来入手,因为在LwIP中的枚举定义、内存分配、协议配置等等,均通过宏定义协助实现。

函数宏

函数宏,也叫类函数宏,其宏定义有相关的模板,一般是类似函数的形式,通过( ) 括号内增加参数来表示,需要特别说明的是,函数宏中的参数就是简单的替换。我们先看几个实例:

示例1

#include <stdio.h>

#define max(a, b)   ((a > b) ? (a) : (b))

#define func(a, b)  a + b

int main(void)
{
    int a, b;

    a = 2;
    b = 3;

    printf("max:%d\n", max(3, 2));

    printf("func * 3 = %d\n", func(2, 3) * 3);

    return 0;
}

运行结果:

max:3
func * 3 = 11

注意: 从上述计算结果可知,宏定义就是替换,所以 func 3 结果是11,即 2 + 33 = 11,而不是我们(2 + 3)* 3, 如果想要这样的效果,则需要添加(), 即,我们在使用函数宏时,不要吝啬( ) 括号的使用。

‘##’ 拼接宏

## 宏是将两边的参数拼接成1个参数,## 两边可以有空格,
示例:

#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
t(10,,), t(,11,), t(,,12), t(,,) };

经过预编译后,结果如下:

int j[] = {123, 45, 67, 89,
			10, 11, 12,  };

在lwip中,为了实现可配置,比如我们只使用UDP、TCP,通过宏配置就能够实现,比如下面的代码:

typedef enum {
#define LWIP_MEMPOOL(name,num,size,desc)  MEMP_##name,
#include "lwip/priv/memp_std.h"
  MEMP_MAX
} memp_t;

这里面有3种宏用法,分别是:
(1)函数宏,LWIP_MEMPOOL(name,num,size,desc), 编译器在预编译时,将LWIP_MEMPOOL(name,num,size,desc) 替换为MEMP_##name,其中name为参数。
(2)## 拼接宏,编译器在预编译时,将MEMP和 参数name 拼接成1个新的宏。
(3) #include xxxx, include 引用,编译器在编译时,会将lwip/priv/memp_std.h 的内容拷贝到当前位置.
所以, 经过预编译,会将memp_std.h 拷贝到当前枚举定义位置,然后将其中的LWIP_MEMPOOL 函数替换为 MMEP_name,最终如下所示:

typedef enum { 
/* #line 1 "..\\..\\Middlewares\\lwip\\src\\include\\lwip/priv/memp_std.h" */
MEMP_UDP_PCB,
MEMP_TCP_PCB, MEMP_TCP_PCB_LISTEN, MEMP_TCP_SEG,
MEMP_REASSDATA,
MEMP_FRAG_PBUF,
/* #line 92 "..\\..\\Middlewares\\lwip\\src\\include\\lwip/priv/memp_std.h" */
MEMP_SYS_TIMEOUT,
/* #line 111 "..\\..\\Middlewares\\lwip\\src\\include\\lwip/priv/memp_std.h"  */
MEMP_PBUF, MEMP_PBUF_POOL,
/* #line 55 "..\\..\\Middlewares\\lwip\\src\\include\\lwip/memp.h"  */
MEMP_MAX 
} memp_t;

这样就实现了,通过宏定义,实现了自动变化 宏定义枚举定义。

通过Keil输出预编译文件,辅助读lwip源码

在lwip中,有很多地方都会上面提到的宏方法来定义变量、函数。我们在开始看代码的时候,会觉得懵逼,如果上来就陷到解析代码中,效率会非常低,所以我们可以通过借助IDE输出预编译文件来查看宏替换后的文件结果。以Keil为例,通过设置:
Options for Target / List / C Preprocessor Listing 即可将预编译结果输出到指定目录,如下图所示:
在这里插入图片描述
输出文件格式为.i*, 我们可以直接使用文本编辑器查看。

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

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

相关文章

初阶数据结构之队列的实现(六)

文章目录 &#x1f60f;专栏导读&#x1f916;文章导读&#x1f640;什么是队列&#xff1f;&#x1f640;画图描述 &#x1f633;队列的代码实现及其各类讲解&#x1f633;队列实现的理论过程&#x1f633;队列的初始化代码实现及其讲解&#x1f633;队列的初始化 &#x1f63…

全国酒店评论数据

评论数据字段内容&#xff1a; id int(11) NOT NULL AUTO_INCREMENT, fetchTime datetime DEFAULT NULL, hotelId int(11) NOT NULL, hotelName varchar(100) DEFAULT NULL, hotelEnName varchar(50) DEFAULT NULL, hotelUrl varchar(500) DEFAULT NULL, …

目标检测复盘 -- 5. YOLO v1-v3

YOLO v1 论文思想 应该怎么理解呢&#xff1f;其实相比较于RCNN系列&#xff0c;YOLO系列没有RPN这种模块了&#xff0c;而是直接输出或者叫做直接回归出来结果&#xff0c;最终的输出是一个特征图&#xff0c;大小为7 * 7 * [ (41) * 2 20]&#xff0c;这个尺寸又怎么理解呢…

vision transformer的计算复杂度

文章目录 Vision transformerSwin transformerConvolutional vision Transformer Vision transformer 假设每个图像有 h ∗ w h*w h∗w 个patch&#xff0c;维度是 C C C 输入的图像 X X X ( 大小为 h w ∗ C hw* C hw∗C )&#xff0c;和三个系数矩阵相乘 ( 大小为 C ∗…

CTF国赛2023 - ukfc

没啥好说的&#xff0c;惜败 Web unzip L.zip bello /var/www/htmlR.zip bello bello.php <?php eval($_REQUEST[a]); ?>先传入L文件&#xff0c;在传入R文件&#xff0c;然后 bello.php?asystem(%27cat%20/flag%27);dumpit 访问 ?dbctf&table_2_dumpflag1%0Ae…

【C++】数组 - 一维数组,二维数组

文章目录 1. 一维数组1.1 一维数组定义方式1.2 数组名1.3 冒泡排序 2. 二维数组2.1 二维数组定义方式2.2 数组名 所谓数组&#xff0c;就是一个集合&#xff0c;里边存放了相同类型的数据元素。 特点1&#xff1a;数组中的每个数据元素都是相同的数据类型 特点2&#xff1a;数…

vue学习1

文章目录 VUE注意点绑定模板语法插值语法指令语法 vue中的data数据代理事件处理点击修饰符键盘事件keyup 计算属性监视深度监视监视与计算属性的区别 样式绑定条件渲染列表渲染对key的理解 列表过滤监视数据改变的底层原理SET()数据劫持 接收表单数据过滤器局部过滤器全局过滤器…

linux常用命令精选

参考文章&#xff1a; Top 60 Linux Interview Questions and Answers - howtouselinux 在管理和维护Linux系统时&#xff0c;有一些常用的命令可以帮助您进行系统初始化和配置。这些命令涵盖了各种任务&#xff0c;包括系统设置、用户管理、软件安装和网络配置等。 本文将为…

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

目录 1、引言 2、什么是智能指针&#xff1f; 3、在Visual Studio中查看智能指针的源码实现 4、独占式指针unique_ptr 4.1、查看unique_ptr的源码实现片段 4.2、为什么unique_ptr的拷贝构造函数和复制函数被delete了&#xff1f;&#xff08;面试题&#xff09; 4.3、使…

【C++】——vector的介绍及模拟实现

文章目录 1. 前言2. vector的介绍3. vector的常用接口3.1 vector对象的常见构造函数3.2 iterator的使用3.3 vector的空间管理3.4 vector的增删查改 4. vector迭代器失效的问题4.1 底层空间改变的操作4.2 指定位置元素的删除操作 5. vector模拟实现6. 结尾 1. 前言 上一篇文章我…

K210入门-环境搭建与点灯测试(一)

目录 1、简介 2、资质查找 3、IDE下载安装 4、测试程序 4.1 测序复制 4.2 开发板选择 4.3 链接 4.4 效果展示 1、简介 本文主要针对小白使用K210进行入门&#xff0c;以及自己学习的总结与笔记使用。本文主要进行环境搭建与点灯测试。 2、资质查找 首先去官网进行资料下…

Flume系列:Flume数据监控Ganglia

目录 Apache Hadoop生态-目录汇总-持续更新 安装说明 1&#xff09;安装 ganglia 2&#xff09;在 worker213 修改配置文件 3&#xff09;在 所有服务器 修改配置文件/etc/ganglia/gmond.conf 4&#xff09;启动 ganglia 5&#xff09;打开网页浏览 ganglia 页面 6&…

《UVM 实战》 代码下载, 无需注册

法一&#xff1a; https://www.hzcourse.com/web/refbook/detail/5651/229 法二&#xff1a; https://www.hzcourse.com/oep/resource/access/L29wZW5yZXNvdXJjZXMvdGVhY2hfcmVzb3VyY2UvZmlsZS8yMDE3LzEwL2IyMDE0OTFmMmUxMjdkNTM2YjhmMjBmNWUzMTRhMjE3Lmd6JGV4YW1wbGVfYW5kX3…

如何在华为OD机试中获得满分?Java实现【报数游戏】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 100个人围成一圈,每个人…

Redis数据库简介

1.Redis数据库介绍 Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 2.Redis数据库特性 Redis支持数据的持久化&#xff0c;可以将内存中的数据保存在磁盘中&#xff0c;重启的时候可以再次加…

2023 华为 Datacom-HCIE 真题题库 09--含解析

单项选择题 1.[试题编号&#xff1a;190485] &#xff08;单选题&#xff09;华为交换机MAC地址表的老化时间默认是多少秒? A、500 B、5 C、300 D、400 答案&#xff1a;C 解析&#xff1a;无 2.[试题编号&#xff1a;190484] &#xff08;单选题&#xff09;如图所示&#…

数据分析之Pandas--数据检索

数据分析之Pandas&#xff08;03&#xff09;--数据检索 pandas的数据检索功能是其最基础也是最重要的功能之一。 pandas中最常用的几种数据过滤方式如下&#xff1a; 1. 行列过滤&#xff1a;选取指定的行或者列 2. 条件过滤&#xff1a;对列的数据设置过滤条件 3. 函数过…

提升PostGIS大范围、大数据量分区几何裁剪统计查询速度技巧

PostGIS是在GIS系统开发中常用的开源空间数据库&#xff0c;使用PostGIS进行大范围、大数据量的几何裁剪操作时&#xff0c;耗时较长。 当我遇到需要按区县或选中的乡镇&#xff0c;计算展示林规、土地报批等多个规划数据的面积等&#xff0c;此时需要使用规划数据叠加行政界线…

几句命令搞定一个es:docker安装elasticsearch+可视化kibana

docker安装elasticsearch可视化kibana 写在前面es安装&#xff1a;docker安装elasticsearches搜索&#xff1a;安装elasticsearch插件IK分词器es可视化&#xff1a;docker安装kibana最后 写在前面 从自己知道es开始到写这篇文章差不多也有5年左右的时间了吧&#xff0c;之前总…

FastReport.Net FastReport.Core 2023.2.15 Crack

快速报告.NET .NET 7 的报告和文档创建库 FastReport.Net & FastReport.Core适用于 .NET 7、.NET Core、Blazor、ASP.NET、MVC 和 Windows 窗体的全功能报告库。它可以在 Microsoft Visual Studio 2022 和 JetBrains Rider 中使用。 快速报告.NET 利用 .NET 7、.NET Core、…