我有一个看起来像这样的结构:
struct dgm_network_pkt {
char responder[INET_ADDRSTRLEN];
int num;
char **neighbors;
};
该字段num
跟踪已分配和指向的字符数组的数量neighbors
。
现在我想构造一个包含标头和结构的数据包,并发送一个包含此数据包的 UDP 数据包。为了做到这一点,我需要做很多指针运算,以及对 sizeof() 的大量调用。例如,如果我的 header 是enum header hdr;
,我的缓冲区是char *buf;
并且我的 struct 的实例是struct mystruct stc;
,我需要执行以下操作(片段):
buf = malloc(sizeof(stc.num * SIZEOF_EACH_ARRAY) + sizeof(hdr) + sizeof(stc.responder) + sizeof(int));
memcpy(buf, &hdr, sizeof(hdr)); /* Copy over header */
memcpy(buf + sizeof(hdr), &stc.responder, sizeof(stc.responder)); /* Copy 'responder' field */
memcpy(buf + dizeof(hdr) + sizeof(stc.responder), &stc.num, sizeof(int)); /* Copy num field */
然后一个循环复制指向的字符数组neighbors
,再次sizeof()
使用相同的参数多次调用。
如果您愿意看,这里是我用来完成所有这些的功能以供参考,但没有必要回答我的问题,并且可能会增加混乱(添加间接)。
int dismesh_compose_net_pkt(struct dgm_network_pkt *dismesh_sta, char **buf)
{
int i;
int pkt_size;
enum dgm_header dgm_hdr;
pkt_size = dismesh_sta->num * DISMESH_ETH_ADDR_STR + sizeof(dgm_hdr)
+ sizeof(dismesh_sta->responder) + sizeof(int);
dgm_hdr = NETWORK_STATUS_RESP;
if ((*buf = malloc(pkt_size)) == NULL)
return -1;
memcpy(*buf, &dgm_hdr, sizeof(dgm_hdr));
memcpy(*buf + sizeof(dgm_hdr), &dismesh_sta->responder, sizeof(dismesh_sta->responder));
memcpy(*buf + sizeof(dgm_hdr) + sizeof(dismesh_sta->responder), &dismesh_sta->num, sizeof(int));
/* Copy contents of neighbors to buffer */
for (i = 0; i < dismesh_sta->num; i++) {
memcpy(*buf + sizeof(dgm_hdr) + sizeof(dismesh_sta->responder) + sizeof(int) + i * DISMESH_ETH_ADDR_STR,
*(dismesh_sta->neighbors + i), DISMESH_ETH_ADDR_STR);
DGM_LOG("Packed up neighbor %d\n", i);
}
return pkt_size;
}
这里是:
我注意到我sizeof()
一遍又一遍地使用相同的参数调用很多:将结构的内容复制到缓冲区,每个元素的大小等等。有没有更好的方法来做到这一点?我在想我可以在我的头文件中包含一些#defines,比如说,我可以在其中执行#define OFFSET_RESPONDER sizeof(hdr)
, #define OFFSET_NUM OFFSET_RESPONDER + sizeof(mystruct.responder)
, and#define SIZE_HEADER sizeof(dgm_header)
等等。如果保持原样,我会注意到显着的性能损失吗?编译器(在我的情况下是 GCC)是否对此进行了优化?你认为#defines 会降低可读性吗?清理此代码的最佳方法是什么?