如何判断C struct中是否存在某一成员,最开始想法是通过offsetof宏定义
#define offsetof(st, m) \ ((size_t)&(((st *)0)->m)) C语言的offsetof()宏是ANSI C标准库中的一个特性,位于stddef.h头文件中。它用于计算给定结构体或联合体类型中某个成员的偏移量(以字节为单位), 但是这种方式仅能检查存在的成员, 不存在编译会有下面类似报错
XXX.c:11:35: error: ‘struct MyStruct’ has no member named ‘member3’; did you mean ‘member1’? 生成成员名的map C/C++ 不支持反射,与例如 Java 或 C# 不同。这意味着在 C/C++ 中,你不能在运行时"检测"未知结构(或类)的成员,你必须在编译时知道它 - 通常是通过 #include 包含定义结构的头文件。实际上,你不能访问未定义结构的内容 - 只能传递指针。
from https://cplusplus.com/forum/beginner/283156/
同样作者给出了一个解决方案,那就是把对象放到map中, 对于C语言的,可以使用脚本处理一下。
大概思路根据脚本解析结构体,生成包含成员的数组,通过数组判断
# generate_struct_member_array.py import re def filter_content(content): # Remove comments content = re.sub(r'\/\*[\s\S]*?\*\/|\/\/.*', '', content) # Remove #define statements content = re.sub(r'#define\s+\w+\s+\w+', '', content) return content def parse_header(header_content): struct_pattern = re.compile(r'struct\s+(\w+)\s*{([^}]*)};', re.DOTALL) structs = struct_pattern.findall(header_content) struct_member_arrays = [] for struct_name, struct_body in structs: members = re.findall(r'\b\w+\s+(\w+)\s*(?:\[\w*\])?;', struct_body) struct_member_arrays.append((struct_name, members)) return struct_member_arrays def generate_array_code(struct_member_arrays): code = "" for struct_name, members in struct_member_arrays: code += f"const char *{struct_name}_member_names[] = {{\n" for member in members: code += f'\t"{member}",\n ' code = code.rstrip(', ') code += "};\n" return code def write_to_file(file_path, content): with open(file_path, 'w') as output_file: output_file.write(content) def read_and_generate(input_file_path, output_file_path): # Read the input header file content with open(input_file_path, 'r') as header_file: header_content = header_file.read() # Filter content (remove comments and #define statements) filtered_content = filter_content(header_content) # Parse the header file struct_member_arrays = parse_header(filtered_content) # Generate code for arrays array_code = generate_array_code(struct_member_arrays) # Write generated code to a new file write_to_file(output_file_path, array_code) print(f"Generated code has been written to {output_file_path}") # Specify the path to the input header file and the output header file input_header_file_path = 'hello.h' output_header_file_path = 'generated_define.h' # Read the input header file, generate code, and write to the output header file read_and_generate(input_header_file_path, output_header_file_path) hello.h
...