https://www.codeleading.com/article/85491893264/
对于lwip中内存池的大小,不同的lwip版本定义的方式不一样,但都大同小异。
在lwip_1.4.1中,通过一个static函数获取内存池大小:
u32_t memp_get_memorysize(void) { u32_t length=0; length=( MEM_ALIGNMENT-1 #define LWIP_MEMPOOL(name,num,size,desc) + ((num)*(MEMP_SIZE+MEMP_ALIGN_SIZE(size))) #include \"lwip/memp_std.h\" ); return length; }
在lwip_2.0中,内存池的大小为:
1 static u8_t memp_memory [ MEM_ALIGNMENT - 1 2 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) 3 #include "lwip/memp_std.h" 4 ];
这两段代码存在于lwip的memp.c中。看到这个memp_memory数组,是不是在怀疑自己的眼睛?这到底是不是一个数组呢?定义的数组里竟然还有两个关键字(include和define)?作者这是在干嘛呢?
不过在整理脉络之后,你不得不佩服lwip作者写代码的能力。现在我们就来尝试理解一下这个memp_memory数组。
LWIP_MEMPOOL宏是在数组中定义的,那么在数组中定义的宏和在全局定义的宏有什么不同呢?是作用域不同还是有其他什么差别?
其实,宏定义的作用域是同文件内从定义开始起作用,直到取消定义(undef)为止。那么mem_memroy数组等价于:
1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) 2 static u8_t memp_memory [ MEM_ALIGNMENT - 1 3 #include "lwip/memp_std.h" 4 ];
这里的 LWIP_MEMPOOL(name,num,size,desc) 定义成了 + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
include关键字其实就是把lwip/memp_std.h
包含进数组。我们来看看memp_std.h
中的部分代码:
1 #if LWIP_RAW 2 LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") 3 #endif /* LWIP_RAW */ 4 5 #if LWIP_UDP 6 LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") 7 #endif /* LWIP_UDP */ 8 9 #if LWIP_TCP 10 LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") 11 LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") 12 LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") 13 #endif /* LWIP_TCP */ 14 15 #undef LWIP_MEMPOOL
我们将这段代码用include包含到 memp_memory 数组中,即:
1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) 2 static u8_t memp_memory [ MEM_ALIGNMENT - 1 3 + (LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB")) 4 + (LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB")) 5 + ... 6 ]; 7 #undef LWIP_MEMPOOL
这样就能清晰的看到memp_memory数组的大小了。在mem_memory数组之前用define定义了LWIP_MEMPOOL,在memp_memory数组定义后,用undef取消了LWIP_MEMPOOL的定义。
同理,memp_get_memorysize函数可以展开为
1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) 2 u32_t memp_get_memorysize(void) 3 { 4 u32_t length=0; 5 length=( 6 MEM_ALIGNMENT-1 7 + (LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB")) 8 + (LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), UDP_PCB")) 9 + ... 10 ); 11 return length; 12 } 13 #undef LWIP_MEMPOOL
所以宏定义的作用域是同文件内从定义开始起作用,直到取消定义(undef)为止。可见lwip的作者写代码是多么的牛逼啊~