Есть ли способ сделать общий код с настройкой макросов на языке C?

Вот полный рабочий пример того, как использовать модули Jackson для работы @JsonRawValue в обоих направлениях (сериализация и десериализация):

public class JsonRawValueDeserializerModule extends SimpleModule {

    public JsonRawValueDeserializerModule() {
        setDeserializerModifier(new JsonRawValueDeserializerModifier());
    }

    private static class JsonRawValueDeserializerModifier extends BeanDeserializerModifier {
        @Override
        public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc, BeanDeserializerBuilder builder) {
            builder.getProperties().forEachRemaining(property -> {
                if (property.getAnnotation(JsonRawValue.class) != null) {
                    builder.addOrReplaceProperty(property.withValueDeserializer(JsonRawValueDeserializer.INSTANCE), true);
                }
            });
            return builder;
        }
    }

    private static class JsonRawValueDeserializer extends JsonDeserializer<String> {
        private static final JsonDeserializer<String> INSTANCE = new JsonRawValueDeserializer();

        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            return p.readValueAsTree().toString();
        }
    }
}

Затем вы можете зарегистрировать модуль после создания ObjectMapper:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JsonRawValueDeserializerModule());

String json = "{\"foo\":\"one\",\"bar\":{\"A\":false}}";
Pojo deserialized = objectMapper.readValue(json, Pojo.class);
3
задан pineaup 18 January 2019 в 11:42
поделиться

1 ответ

Подстановка макроса для 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
0
ответ дан Bodo 18 January 2019 в 11:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: