首页
社区
课程
招聘
[原创]C/C++技巧 变长数据
2021-2-16 00:34 5999

[原创]C/C++技巧 变长数据

2021-2-16 00:34
5999

比如在进行网络收发数据时,数据的长度不可变的,一般我们是这样定义数据的。

1
2
3
4
5
6
typedef struct _PROTOCOL_STRUCT
{
     int nLen;
     unsinged char pBuffer[1]; //gun linux可定义为0的数组
} PROTOCOL_STRUCT,*PPROTOCOL_STRUCT;
int nTotal = GetOffset(PROTOCOL_STRUCT,pBuffer[0]) + sizeof(UCHAR)*n;

这里计算数据的长度使用了 C/C++技巧 结构体成员偏移 的内容。

 

由于windows使用了标准的c/c++,故无法声名0个数的数组,gun linux可以的。
使用这种方法,可以获取每一个实际数据字节。
例如:

1
2
3
4
5
6
7
PROTOCOL_STRUCT pProtocolData = NULL;
....
for(int i=0;i<pProtocolData->nLen;i++)
{
    unsigned char data = pProtocolData->pBuffer[i];
    //do something
}

这里使用了数组与指针转换的技巧。

 

其实我们在c/c++定义的数组,结构体,类等各种我们认为有意义的数据类型,其实只是一种连续内存的数据组织方式,而编译器自动会进行偏移计算获取其数据。
所以说,这种有意义的结构体只是对我们编程者来说有界限的,但对编译器来说,其都只是数据内存,只是偏移不同而已。
http://code.bytekits.com/ccpp-skill/ccpp-skill-var-data.html


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2021-2-16 00:53 被tsingchen编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (2)
雪    币: 4398
活跃值: (1241)
能力值: ( LV7,RANK:113 )
在线值:
发帖
回帖
粉丝
Adventure 2021-2-18 00:11
2
0
#include "stdafx.h"
#include <windows.h>

struct Msg
{
	char nothing;
	int len;
	char buf[1];
};

int _tmain(int argc, _TCHAR* argv[])
{
	struct Msg* msg = (struct Msg*)new char(20);

	int size = sizeof(msg->len) + sizeof(msg->nothing);

	printf("size:%d\n", size);			// size = 5

	size = FIELD_OFFSET(struct Msg, buf);
	printf("actual size:%d\n", size);		// size = 8

	return 0;
}

如果再补充一下可变数组配合FIELD_OFFSET宏一起使用的例子就更好了!


雪    币: 27
活跃值: (127)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Xenophon 2021-2-20 13:50
3
0
typedef struct _PROTOCOL_DATA {
    UINT Length;
    BYTE Buffer[];
} PROTOCOL_DATA;

个人习惯写空白,写个 0 感觉怪怪的。微软头文件中的默认都是 1。
在计算偏移量时,写成员名 Buffer 即可,不用 Buffer[0]。

标准 C 库已经包含 offsetof 这个宏:

offsetof(PROTOCOL_DATA, Buffer);

包含 windows.h 的情况下可以用:

FIELD_OFFSET(PROTOCOL_DATA, Buffer);


游客
登录 | 注册 方可回帖
返回