1、如何将数据传递给 FuncHandle(int event, void *inParam, int inParamSize) 类型的数据?为什么要使用 void *类型接收传入参数,有何优点?
2、整数、字符串作为参数传给给 void *inParam 参数时,如何传递?(hex数据存储到数组中)
3、柔性数组的使用:某数据(结构体、申请的内存的数据、数组等)作为柔性数组的参数,传递给某函数FuncHandle(void *inParam, int inParamSize); 当FuncHandle() 函数进行处理时,需按传入数据的结构,按层次进行解析;
【详解如下:】
1、如何将数据传递给 FuncHandle(int event, void *inParam, int inParamSize) 类型的数据?为什么要使用 void *类型接收传入参数,有何优点?
—— 解答:
typedef struct {
int sex;
int age;
char name[20];
char data[]; /* 柔性数组,sizeof(PersonInfoType) 不占内存空间 */
} PersonInfoType;
/* 如下结构体中,如果有复杂的数据类型,也可以在结构中增加 柔性数组成员 */
typedef struct {
unsigned int moneyOneMonth;
unsigned int wokeTimeOneDay;
char companyAddr[128];
} JobWokerInfo;
typedef struct {
unsigned int age;
unsigned int mathScore;
unsigned int allStudent;
char schoolAddr[128];
} StudentInfo;
typedef struct {
unsigned int age;
unsigned int teachType;
unsigned int haveStudent;
unsigned int allTeacher;
char schoolAddr[128];
} teacherInfo;
int FuncHandle(int eventId, void *inParam, int inParamSize)
{
if ((inParam == NULL) || (inParamSize == 0)) {
printf("error\n");
return -1;
}
PersonInfoType *info = (PersonInfoType *)inParam;
printf("sex: %d, age: %d, name: %s\n", info->sex, info->age, info->name);
switch () {
case EVENT_TYPE_STUDENT: {
StudentInfo *infoData= (StudentInfo *)info->data;
printf("%d, %d, %d, %s\n", infoData->age, infoData->mathSocre, infoData->allStudent, infoData->schoolAddr);
break;
}
case EVENT_TYPE_TEACHER: {
teacherInfo *infoData= (teacherInfo *)info->data;
printf("%d, %d, %d, %d, %s\n", infoData->age, infoData->teachType, infoData->haveStudent, infoData->allTeacher, infoData->schoolAddr);
break;
}
case EVENT_TYPE_JOB_WOKER: {
JobWokerInfo *infoData= (JobWokerInfo *)info->data;
printf("%d, %d, %s\n", infoData->moneyOneMonth, infoData->wokeTimeOneDay, infoData->companyAddr);
break;
}
default: {
printf("event is not error\n", event);
return -1;
}
}
FuncHandleOtherFlow();
return 0;
}
1)根据FuncHandle() 函数处理中数据的类型,按类型对数据进行封装,然后传入;就类比进程间通信,数据的发送、解析数据的结构必须一致;如上代码中,switch() 流程中,每个case 类型对应的数据结构不同,所以处理函数也就不同,处理函数需将传入的参数转换为相应的类型后,即能获取到实际数据,否则解析数据很可能不正确;
2)使用 void *inParam 的好处:主要应用在某事件类型(比如MCU上报的数据,不同的数据类型都是走同一条核间通信通道,数据接收后,就需按照相应的数据类型来解析,方可成功解析上传的数据)、或者回调函数相同,即不同类型的数据,传递不同结构的数据参数,但函数使用同一个函数来处理数据 ( int event, void *inParam)相对来说就容易处理:只需在回调函数中,根据数据的类型区分出不同的数据,再更加数据的长度,即可memcpy() 实际的数据体;
typedef struct {
int event;
unsigned int dataLen;
char data[0]; // char data[]; 或者此处仍然是一个复杂数据类型Type_ST(结构体),但结构体的内部有柔性数据,如果是这样,dataLen 就不再是柔性数据的长度了,Type_ST 结构中的 data_Len 应该表示柔性数组的长度。
}
2、整数、字符串作为参数传给给 void *inParam 参数时,如何传递?(如果是hex数据作为参数呢?)
—— 解答:
char data01[] = {"01234567890abcdef"};
char data02[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
char data03[] = {"01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"};
typedef struct {
int event;
int dataType;
int dataLen;
int data[0]; // int data[]; 柔性数组,未申请内存时,不占内存空间。
} EventDataInfo;
1)如上数组数据,都通过 sizeof(数组名)求得数据实际所占的内存空间是否正确?
实际上data01 和 data03 是字符串数据,需要使用 strlen(数组名) 来计算数据实际所占用的内存空间,而sizeof(data01) 和 sizeof(data02) 都是对指针(即数据名)来计算长度,其结果是 4字节。
2)无论存储的是字符串,还是整形数据,存储到 EventDataInfo 结构体的柔性数组data中时,首先需要给柔性数据申请内存空间,然后通过 memcpy_s() 来将数据拷贝到柔性数组中。
3)dataLen 表示 当前柔性数组中存储的数据大小,而非 sizeof(EventDataInfo) 结构大小 + 申请的柔性数组空间大小。
3、柔性数组的使用:某数据(结构体、申请的内存的数据、数组等)作为柔性数组的参数,传递给某函数FuncHandle(void *inParam, int inParamSize); 当FuncHandle() 函数进行处理时,需按传入数据的结构,按层次进行解析;
—— 解答:万变不离其宗:无论数据是什么,通信双方需要协商好通信的数据格式,且数据格式必须满足应用需要,如果涉及不同类型的数据,要能够区分上传的数据类型,以便合理的解析。