Looping through elements in a struct in C for extr

2019-07-14 05:30发布

问题:

I have a requirement where I have a big structure in C consisting of around more than 30 different elements of different data types:

typedef struct {
  type1 element1;
  type2 element2;
  type3 element3;
  type2 element4[10];
  ...
  typeN elementN;
} my_messg_struct;

where this is basically a group of elements in a message sent over the serial protocol. This message has various elements of varying datatypes as captured in the above structure. Similarly, I have a lot of other messages as well. Now I have to write a generic function which is responsible for reading these message structs and loop through each of the elements reading the element's value and datatype and then transmitting over the serial port. I need to read the datatype first because the order of transmission of various datatypes is different in my case.

So, basically, I just wanted to know how to loop through elements of a struct in C in such a way that I can read the value and data type of each of the element present in a struct?

回答1:

You could try to use X macros, but the resulting source code readability is questionable:

 #include <stdio.h>

 #define LIST_OF_VARIABLES \
     XI(int, value1) \
     XD(double, value2) \
     XU(unsigned, value3)


 #define XI(int, name) int name;
 #define XD(double, name) double name;
 #define XU(unsigned, name) unsigned name;
 typedef struct A {
     LIST_OF_VARIABLES
 } A;
 #undef XI
 #undef XD
 #undef XU

 void print_variables(struct A a)
 {
 #define XI(type, name) printf("%s = %d\n", #type, a.name);
 #define XD(type, name) printf("%s = %f\n", #type, a.name);
 #define XU(type, name) printf("%s = %u\n", #type, a.name);
 LIST_OF_VARIABLES
 #undef XI
 #undef XD
 #undef XU
 }

 int main(void) {
     A a = {
         .value1 = 10,
         .value2 = 0.5,
         .value3 = 1,
     };
     print_variables(a);
     return 0;
 }

Now that you have a type string placed on every #type occurrence you could use some string comparison functions to determine what to based for each type.



回答2:

C does not support traveling on struct members (something like reflection at C#,Java). You'll need to wrap each element with a struct stating its size, type and data. something like this:

typedef enum {
    et_int,
    et_long,
    et_string,
    et_array
}element_type_t;

struct element {
    element_type_t type;
    int element_length;
    void *data;
};

BTW, there is a way to get reflection for struct, if one is using google protocol buffers. (see https://en.wikipedia.org/wiki/Protocol_Buffers) this way you can ask for each struct which members it has and of which type. however using this, involves using protocol buffer compiler and adding protocol buffer files to your project.



标签: c struct