有没有办法用C语言的宏设置来执行通用代码?

时间:2019-01-18 10:33:55

标签: c macros generic-programming

我有一个代码,可以管理许多不同的产品。 变量及其特性由X宏设置。

每个产品的5个功能(共10个)具有相同的过程,但前缀和宏不同。

我想把这些功能归为通用。

文件product_1.c

void product_1_init(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_A;
  PRODUCT1_XMACRO_LOCAL_DATA
  PRODUCT1_XMACRO_UART_DATA
#undef DATA
}

void product_1_format_data_uart(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_B;
  PRODUCT1_XMACRO_UART_DATA
#undef DATA
}
...

文件product_2.c

void product_2_init(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_A;
  PRODUCT2_XMACRO_LOCAL_DATA
  PRODUCT2_XMACRO_UART_DATA
#undef DATA
}

void product_2_format_data_uart(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_B;
  PRODUCT2_XMACRO_UART_DATA
#undef DATA
}
...

我想知道是否可以做这样的事情:

文件product_generic.c

#define PRODUCT_FUNC(name) PRODUCT_FUNC_(PRODUCT_GEN_NAME, name)
#define PRODUCT_FUNC_(prefix, name)  PRODUCT_FUNC__(prefix, name)
#define PRODUCT_FUNC__(prefix, name) prefix ## name

void PRODUCT_FUNC(_init)(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_A;
  PRODUCT_GEN_XMACRO_LOCAL_DATA
  PRODUCT_GEN_XMACRO_UART_DATA
#undef DATA
}

void PRODUCT_FUNC(_format_data_uart)(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_B;
  PRODUCT_GEN_XMACRO_UART_DATA
#undef DATA
}
...
//put here every function with process in commun to every product

文件product_1.c

#define PRODUCT_GEN_NAME product_1
#define PRODUCT_GEN_XMACRO_LOCAL_DATA PRODUCT1_XMACRO_LOCAL_DATA
#define PRODUCT_GEN_XMACRO_UART_DATA PRODUCT1_XMACRO_UART_DATA

#include "product_generic.c"  /*doesn't work*/

#undef PRODUCT_GEN_NAME
#undef PRODUCT_GEN_XMACRO_LOCAL_DATA
#undef PRODUCT_GEN_XMACRO_UART_DATA

文件product_2.c

#define PRODUCT_GEN_NAME product_2
#define PRODUCT_GEN_XMACRO_LOCAL_DATA PRODUCT2_XMACRO_LOCAL_DATA
#define PRODUCT_GEN_XMACRO_UART_DATA PRODUCT2_XMACRO_UART_DATA

#include "product_generic.c" /*doesn't work*/

#undef PRODUCT_GEN_NAME
#undef PRODUCT_GEN_XMACRO_LOCAL_DATA
#undef PRODUCT_GEN_XMACRO_UART_DATA

我的主要问题是在不同的产品文件中如何“ #include product_generic.c”。

编译器不想包含'.c'文件,我们不能将功能放在'.h'文件中。

1 个答案:

答案 0 :(得分:3)

PRODUCT_GEN_XMACRO_LOCAL_DATA的宏替换应该起作用,但是void PRODUCT_GEN_NAME ## _init(void* p_generic_ptr)无效。

您只能在预处理器宏中使用##,并且要串联的至少一部分必须是宏参数。

_file product_generic.c _

/* add fixed PRODUCT_GEN_NAME as prefix */
#define PRODUCT_FUNC(name) PRODUCT_FUNC_(PRODUCT_GEN_NAME, name)
/* next macro call necessary to get PRODUCT_GEN_NAME expanded before ## */
#define PRODUCT_FUNC_(prefix, name)  PRODUCT_FUNC__(prefix, name)
/* and finally concatenate the parts */
#define PRODUCT_FUNC__(prefix, name) prefix ## name

/* you could also use the second macro here */
/* void PRODUCT_FUNC_(PRODUCT_GEN_NAME,_init)(void* p_generic_ptr) */
void PRODUCT_FUNC(_init)(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_A;
  PRODUCT_GEN_XMACRO_LOCAL_DATA
  PRODUCT_GEN_XMACRO_UART_DATA
#undef DATA
}

void PRODUCT_FUNC(_format_data_uart)(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_B;
  PRODUCT_GEN_XMACRO_UART_DATA
#undef DATA
}
...
//put here every function with process in commun to every product

添加到问题中的第二个问题的建议解决方案

如果既不允许包含C文件,也不允许在头文件中定义函数,则可以使用包含product_generic.c的单个文件#include "product_definitions.h",并使用具有相同名称但特定于产品的包含文件在不同的位置

product_1/product_definitions.h
product_2/product_definitions.h
...

与产品特定的编译命令结合使用不同的包含目录和不同的输出文件。像这样

cc -I product_1 product_generic.c -o product_1.c
cc -I product_2 product_generic.c -o product_2.c
...

_file product_generic.c _

#include "product_definitions.h"

/* add fixed PRODUCT_GEN_NAME as prefix */
#define PRODUCT_FUNC(name) PRODUCT_FUNC_(PRODUCT_GEN_NAME, name)
/* next macro call necessary to get PRODUCT_GEN_NAME expanded before ## */
#define PRODUCT_FUNC_(prefix, name)  PRODUCT_FUNC__(prefix, name)
/* and finally concatenate the parts */
#define PRODUCT_FUNC__(prefix, name) prefix ## name

void PRODUCT_FUNC(_init)(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_A;
  PRODUCT_GEN_XMACRO_LOCAL_DATA
  PRODUCT_GEN_XMACRO_UART_DATA
#undef DATA
}

void PRODUCT_FUNC(_format_data_uart)(void* p_generic_ptr)
{
#define DATA(v1,...,v20) PROCESS_B;
  PRODUCT_GEN_XMACRO_UART_DATA
#undef DATA
}
...
//put here every function with process in commun to every product

_file product_1 / product_definitions.h _

#define PRODUCT_GEN_NAME product_1
#define PRODUCT_GEN_XMACRO_LOCAL_DATA PRODUCT1_XMACRO_LOCAL_DATA
#define PRODUCT_GEN_XMACRO_UART_DATA PRODUCT1_XMACRO_UART_DATA