Есть ли способ сделать общий код с настройкой макросов на языке C? - PullRequest
0 голосов
/ 18 января 2019

У меня есть код, который управляет множеством различных продуктов. Переменные и их характеристики задаются макросом X.

5 функций (из 10) по продуктам, которые имеют одинаковый процесс с другим префиксом и другим макросом.

Я хотел бы поставить эти функции как общие.

file 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

file 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 голосов
/ 18 января 2019

Подстановка макроса для 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...