Управление избыточными определениями типов от нескольких поставщиков

Глобальные переменные, которые не имеют явного инициализатора, выделяются в разделе BSS в исполняемом файле. Они на самом деле не занимают места в EXE; раздел BSS является специальным разделом, который ОС выделяет и очищает для обнуления. В других операционных системах существуют подобные механизмы.

можно зависеть от инициализируемых нулем глобальных переменных.

7
задан Jon 10 December 2009 в 19:25
поделиться

5 ответов

Один из возможных способов сделать это без изменения заголовок поставщика будет использовать препроцессор с некоторыми оболочками заголовка, например

mytypes.h

#define BYTE VENDOR1_BYTE
#include <vendor1/types.h>
#undef BYTE

#define BYTE VENDOR2_BYTE
#include <vendor2/types.h>
#undef BYTE

typedef unsigned char BYTE;

. Это приведет к тому, что код поставщика будет генерировать различные определения типов, но, надеюсь, сопоставлен с одним и тем же фактическим типом (unsigned char в примере). Если поставщики используют разные базовые типы для одних и тех же имен типов, этот метод, скорее всего, не будет работать.

h

#define BYTE VENDOR1_BYTE
#include <vendor1/types.h>
#undef BYTE

#define BYTE VENDOR2_BYTE
#include <vendor2/types.h>
#undef BYTE

typedef unsigned char BYTE;

Это приведет к тому, что код поставщика будет генерировать разные определения типов, но, надеюсь, сопоставлен с одним и тем же фактическим типом (unsigned char в примере). Если поставщики используют разные базовые типы для одних и тех же имен типов, этот метод, скорее всего, не будет работать.

h

#define BYTE VENDOR1_BYTE
#include <vendor1/types.h>
#undef BYTE

#define BYTE VENDOR2_BYTE
#include <vendor2/types.h>
#undef BYTE

typedef unsigned char BYTE;

Это приведет к тому, что код поставщика будет генерировать разные определения типов, но, надеюсь, будет отображен на один и тот же фактический тип (unsigned char в примере). Если поставщики используют разные базовые типы для одних и тех же имен типов, этот метод, скорее всего, не будет работать.

6
ответ дан 7 December 2019 в 03:16
поделиться

Это круто. Если бы мне пришлось что-то делать, я бы, вероятно, зажал нос и модифицировал сторонние файлы заголовков - возможно, используя макросы для получения условной компиляции ошибочных определений типов.

Удачи.

2
ответ дан 7 December 2019 в 03:16
поделиться

One approach, although it could be a lot of work, is to build your own "wrapper" layers which provide only the functionality you need from each of the middleware vendors. If you keep each wrapper in its own compilation unit (.c file) that's the only place you'll need to refer to the vendor's header file. That gives you a way to prevent the conflicting types from "leaking" into your application, as you can use your own typedefs and translate them to the vendor-specific types in the wrapper.

As Steve suggested, modifying the header files might be the best solution, depending on how often the vendor ships new versions of their stuff. The overhead could get pretty high.

0
ответ дан 7 December 2019 в 03:16
поделиться

Если у вас есть возможность использовать компиляцию C ++ для вашего собственного кода (даже если это, по сути, код C), вы можете создать оболочки пространства имен следующим образом:

vendorA_target.h

namespace vendorA
{
    extern "C"
    {
        #include <target.h>
    }
}

vendorB_OS_types.h

namespace vendorB
{
    extern "C"
    {
        #include <target.h>
    }
}

Затем в вашем собственном коде. включить эти заголовки вместо оригиналов и использовать разрешение области видимости, или если вы уверены, что типы с тем же именем имеют идентичные или совместимые определения, просто используйте директиву using:

using vendorB::WORD
WORD timeout = 100 ;

vendorA::WORD x = 0xffff ;

Обратите внимание, что оболочки extern «C» не нужны, если заголовки уже имеют их внутри в __ cplusplus макросах, но это не повредит.

Использование C ++ для компиляции кода C не накладывает никаких накладных расходов, но имеет более строгую проверку соответствия типов, что, хотя и хорошо для качества вашего кода, может вызвать другие головные боли; особенно если сторонние заголовки содержат код, недопустимый как C ++. Если заголовки уже содержат объявления extern «C» в __ cplusplus макросах, то они уже предназначены для «C ++ - готовых», и у вас может не быть таких проблем.

К сожалению, этот метод не решает проблему макросов препроцессора с тем же именем. Если у вас возникла эта проблема, вам, возможно, придется #undef макросы из одного заголовка, прежде чем включать другой, или изменить заголовки.

0
ответ дан 7 December 2019 в 03:16
поделиться

Если поставщик реагирует на отзывы, вы можете попросить его переместить эти определения универсальных типов в отдельный файл, например types.h . Если они изолированы в отдельном файле, им намного проще управлять. Решение может быть таким простым, как удаление их types.h и добавление вашего собственного проекта types.h , который может делать все, что ему нужно, в вашем проекте.

Даже лучше, попросите их использовать стандартные определения типов C в stdint.h , то есть uint16_t .

В противном случае я бы предложил модификацию файлов заголовков поставщика, сделанную так чисто насколько это возможно, чтобы его было легко переделать при следующем выпуске кода. Конечно, все это происходит в вашей VCS, поэтому вы можете точно отслеживать, какие изменения вы внесли!

1
ответ дан 7 December 2019 в 03:16
поделиться
Другие вопросы по тегам:

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