我正在处理一个C语言项目。我发现根据某些规则可以自动生成大量代码。例如,如果我只是指定一些C结构体,那么就可以基于它们自动生成代码。我知道这是可行的,但我以前没有尝试过。有经验的C程序员能否提供一些指导或分享如何在最小工程投入下完成此类工作的经验?
编辑:具体而言,我是否需要编写一个自定义C解析器来完成所有这些操作,还是有更简单的方法来处理这个问题?
编辑:具体而言,我是否需要编写一个自定义C解析器来完成所有这些操作,还是有更简单的方法来处理这个问题?
我见过的一种有效方法是使用宏(通常被人所厌恶的工具)。宏有两个特点可以帮助使生活变得更加容易,单个井号‘#’可以将参数转换为字符串,例如#_name
将会被翻译成"fieldName1"
,双井号‘##’可以将参数与其他内容连接起来,从而可以扩展新的内容,例如STRUCT_##_type##_str
将会被翻译成STRUCT_int_str
,然后被翻译成"%d"
首先将结构体或“描述”包装在宏中,即放到一个单独的文件中(the-struct.def)
STRUCT_BEGIN(s_my_struct)
STRUCT_FIELD(int, fieldName1)
STRUCT_FIELD(int, fieldName2)
STRUCT_FIELD(int, fieldName3)
STRUCT_END(s_my_struct)
// Note that you can add more structs here and all will automatically get defined and get the print function implemented
那么,在需要声明或实现应处理结构的地方,可以以不同方式定义宏。例如:
#define STRUCT_BEGIN(_name) struct _name {
#define STRUCT_END(_name) };
#define STRUCT_FIELD(_type, _name) _type _name;
#include "the-struct.def"
// then undef them
#undef STRUCT_BEGIN
#undef STRUCT_END
#undef STRUCT_FIELD
并且需要创建一个打印该结构的函数
#define STRUCT_BEGIN(_name) void print_ ## _name(struct _name *s) {
#define STRUCT_END(_name) }
#define STRUCT_FIELD(_type, _name) printf("%s = " STRUCT_##_type##_str "\n", #_name, s->_name);
#define STRUCT_int_str "%d" /* this is to output an int */
// add more types...
#include "the-struct.def"
// then undef them
#undef STRUCT_BEGIN
#undef STRUCT_END
#undef STRUCT_FIELD
#undef STRUCT_int_str
其他用途可以是自动生成函数来交换字节等。
这里提供了一个小例子:https://gist.github.com/3786323
在C语言中,进行元编程的相对传统的方法之一是使用类似于X宏技术的技巧。
本质上,与其使用普通的C结构声明,更好的方法是完全使用宏来定义结构,像这样:
BEGIN_STRUCT(pointf)
FIELD(float, x)
FIELD(float, y)
END_STRUCT(pointf)
将这些定义放在一个没有多重包含保护的头文件中。
然后,对于需要生成的每个代码片段(包括基本结构),#define
每个元语言宏,#include
定义头文件,并再次#undef
元语言宏:
#define BEGIN_STRUCT(N) struct N {
#define FIELD(T,N) T N;
#define END_STRUCT(N) }
#include "definitions.h"
#undef BEGIN_STRUCT
#undef FIELD
#undef END_STRUCT