- 论坛徽章:
- 36
|
回复 3# yulihua49
这几次尝试着去实现一个简单的例子,发现不好实现,而且不论看上去还有实现上都觉得好丑陋,
位域,结构体的支持这些想不到好办法。看来真是瞎折腾。C语言还是简单就好吧。
packet.h:- #ifndef _HAVE_PACKET_H
- #define _HAVE_PACKET_H
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- enum field_class {
- base,
- packet,
- array,
- bits,
- bit,
- N_FIELD_CLASS
- };
- struct packet_desc {
- char const *pkt_name;
- size_t pkt_size;
- size_t packed_size;
- size_t n_fields;
- size_t *field_offsets;
- size_t *field_sizes;
- size_t *field_class;
- char const **field_names;
- char const **field_types;
- };
- /* _ inner-define
- * */
- #define _DEFINE_base( type, name, size) type name;
- #define _DEFINE_ref( type, name, size) type name;
- #define _DEFINE_array(type, name, size) type name[size];
- #define _DEFINE_bit( type, name, size) type name:size;
- #define _DEFINE_bits( type, name, size) \
- struct {\
- name(DEFINE) \
- }name;
- #define _DEFINE_packet(type, name, size) \
- struct name { \
- name(DEFINE) \
- }name;
- #define _SIZEOF_END(type, name, size) name),
- #define SIZEOF_END(name) _SIZEOF_END
- #define _SIZEOF_FIELD(name) sizeof(((struct name*)0)-> SIZEOF_END
- #define _COUNT_FIELD( type, name, size) +1
- #define _PACKED_END(type, name, size) name)
- #define PACKED_END(name) _PACKED_END
- #define _PACKED_FIELD(name) +sizeof(((struct name*)0)-> PACKED_END
- #define _STRING_TYPE( type, name, size) #type,
- #define _STRING_NAME( type, name, size) #name,
- #define _NULL_FIELD( type, name, size)
- #define _OFFSET_END( type, name, size) name),
- #define OFFSET_END(name) _OFFSET_END
- #define _OFFSET_FIELD(name) __builtin_offsetof(struct name, OFFSET_END
- #define DEFINE(CLASS) _DEFINE_##CLASS
- #define COUNT_FIELD(CLASS) _COUNT_FIELD
- #define SIZEOF_FIELD(CLASS) _SIZEOF_FIELD(CLASS)
- #define PACKED_FIELD(CLASS) _PACKED_FIELD(CLASS)
- #define STRING_TYPE(CLASS) _STRING_TYPE
- #define STRING_NAME(CLASS) _STRING_NAME
- #define CLASS_FIELD(CLASS) CLASS,_NULL_FIELD
- #define OFFSET_FIELD(CLASS) _OFFSET_FIELD(CLASS)
- #define PACKET(name) \
- struct name{ \
- name(DEFINE) \
- }; \
- struct packet_desc name##_desc = { \
- .pkt_name = #name, \
- .pkt_size = sizeof(struct name),\
- .n_fields = name(COUNT_FIELD),\
- .packed_size = name(PACKED_FIELD(name)),\
- .field_offsets = (size_t[]) { name(OFFSET_FIELD(name))},\
- .field_sizes = (size_t[]) { name(SIZEOF_FIELD(name)) },\
- .field_class = (size_t[]) { name(CLASS_FIELD) },\
- .field_types = (char const *[]){ name(STRING_TYPE) },\
- .field_names = (char const *[]){ name(STRING_NAME) },\
- };
- static inline void define_printf(struct packet_desc *desc)
- {
- size_t n_field = 0;
- printf("struct %s {\n", desc->pkt_name);
- for (n_field = 0; n_field < desc->n_fields; n_field++) {
- printf("\t%-16s%16s;\t/*%4d%4d */\n",
- desc->field_types[n_field],
- desc->field_names[n_field],
- desc->field_offsets[n_field],
- desc->field_sizes[n_field]
- );
- }
- printf("\n\t/* size: %d, members: %d */\n"
- "\t/* sum members: %d */\n",
- desc->pkt_size,
- desc->n_fields,
- desc->packed_size);
- printf("};\n");
- }
- #endif /* _HAVE_PACKET_H */
复制代码 test.c:- #include <stdio.h>
- #include <stdint.h>
- #include "packet.h"
- #define s(_) \
- _(base)(int, hh, -)\
- _(base)(int, jj, -)\
- _(base)(int, kk, -)
- PACKET(s)
- #define world(_) \
- _(bit)(int, bita, 4) \
- _(bit)(int, bitb, 4) \
- _(bit)(int, bitc, 28)\
- _(bit)(int, bitd, 4)
- #define sub(_) \
- _(base)(int, hh, -)\
- _(base)(int, jj, -)\
- _(base)(int, kk, -)
- #define hello(_) \
- _(base)(int, a, -) \
- _(base)(short, b, -) \
- _(bits)(struct,world, -) \
- _(packet)(struct sub, sub, -) \
- _(base)(struct s*, ha, -) \
- _(array)(int, c, 12)
- PACKET(hello)
- int main(void)
- {
- struct hello hello;
- define_printf(&hello_desc);
- define_printf(&s_desc);
- }
- #undef s
- #undef world
- #undef hello
复制代码 |
|