在下面的代码中,有人可能会解释一下struct ether_header *eh = (struct ether_header *) sendbuf;
行上发生的事情吗?我知道它正在创建eh
类型的指针ether_header
,并且在RHS上,您将sendbuf
投射为tyoe struct ether_header
的指针。但是你如何才能做到这一点sendbuf
是char array
?你也为什么要这样做?
以下是完整代码send ethernet frame
的链接#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
int main(int argc, char *argv[])
{
int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
int tx_len = 0;
char sendbuf[BUF_SIZ];
struct ether_header *eh = (struct ether_header *) sendbuf;
答案 0 :(得分:1)
但是如果
sendbuf
是char
数组,怎么能这样做是?
代码不应该这样做。
将指针转换为最初不是该类型的有效指针的类型是未定义的行为(UB)。
char sendbuf[BUF_SIZ];
struct ether_header *eh = (struct ether_header *) sendbuf; // UB
至少要考虑struct ether_header
是否要求对齐要求为偶数地址,而sendbuf[]
是否在奇数地址上开始。任务可能会导致程序失效。
第二个问题是未发布的代码可能会在以后对sendbuf[]
和eh
执行哪些违反严格别名规则@Andrew Henle的行为。
更好的方法是使用union
。现在成员已对齐,union
处理严格的别名规则。
union {
char sendbuf[BUF_SIZ];
struct ether_header eh;
} u;
你为什么要这样做?
允许从2种数据类型的角度访问数据。也许要进行u
的数据转储。
答案 1 :(得分:0)
行char sendbuf[BUF_SIZ]
分配一个字符块(即大多数系统上的字节),而演员struct ether_header *eh = (struct ether_header *) sendbuf
表示您明确希望将其视为struct ether_header
类型。除了(可能)设置CPU寄存器外,没有来自此演员的重要指令。
你最终会得到两个指向同一块内存的指针。修改一个会影响另一个。
话虽如此,但它并非完全正确/安全,因为sendbuf
可能无法正确对齐以实际包含struct ether_header
。
编辑:关于结构别名规则,显式允许char*
为任何其他数据类型设置别名,但反过来不一定正确。