是可以用比特而不是字节来做memcpy吗?

我想知道是否可以通过位而不是字节来进行memcpy

我正在为带有VLAN标记的以太网帧编写C代码,其中我需要填写VLAN标头属性(PCP-3bits,DEI-1bit,VID-12bits)的不同值。

如何对这些位执行memcpy,或者以位为单位向这些属性填充值的任何其他可能性。

提前致谢 !

不可以。比特不可寻址(意味着不能直接从内存中读取它们。它们没有地址。只有字节有地址)。

您需要读取包含您感兴趣的位的字节或单词,并自己进行屏蔽 。

如果需要填充字段,可以将C 位字段与struct一起使用,如下所示:

 struct box_props { unsigned first : 1; unsigned second : 3; unsigned : 4; }; 

例如, 1表示该字段长度为1位。 最后一个(未命名的)字段表示:4位填充。

定义structmemcpy并读取字段,就像它们在unsigned 。 写作也一样。

注意 :始终填充整数字节,或memcpy可能会产生不良影响。

我已经为客户端完成了帧的802.1Q VLAN标记,其中只有802.3以太网帧,但由于安装了新的VLAN感知交换机,因此希望迁移到802.1Q。

首先,你不能复制位。 我们使用memcpy以字节为单位复制了标记。

插图(参考维基百科的字段描述): –

VLAN Tag = 4字节; 由TPID(2字节)和TCI(2字节)组成。

TPID很简单,始终为0x8100,表示VLAN标记帧。

TCI由PCP-3bits,DEI-1bit,VID-12bits组成。 将TCI分解为半字节即4位。 默认情况下,半字节(PCP + DEI)= 0x0,假设优先级被禁用且DEI = 0.剩余的3个半字节(12位)用于VLAN-ID本身。 比如,你想为VLAN-ID = 123标记一个帧。在hex中,这将是= 0x07B。

将半字节组合在一起,你有2字节的TCI字段,现在可以看作是0x007B。

然后你可以做到以下。 (代码未编译)

 unsigned short int vlanTPID, vlanTCI; unsigned char *dest, *src; // Set the VLAN Tag vlanTPID = 0x8100; vlanTCI = 0x007B; // Pointer to the TPID position of ethernet frame dest = &vlanTagPosition; src = &vlanTPID; memcpy(dest, src, sizeof(vlanTPID)); // Increment dest pointer by 2 bytes to insert TCI in the ethernet frame dest += 2; src = &vlanTCI; memcpy(dest, src, sizeof(vlanTCI));