Как вы заявили, C++ Builder не поддерживает инструкции препроцессора внутри макросов. Это подтверждается на сайте Embarcadero в:
#define (C++)
После каждого отдельного макроса, дальнейшее сканирование производится вновь расширенного текста. Это позволяет использовать вложенные макросы: расширенный текст может содержать макроопределения, подлежащие замене. Однако, если макрос расширяется в то, что выглядит как предпроцессорная директива, директива не будет распознана препроцессором.
Причиной этого является, потому что #
характер внутри макроса зарезервирован для stringizing оператором препроцессора.
Некоторые компиляторы, включая MSVC, обойти это ограничение с помощью расширения компилятора __pragma()
или расширения C99/C++ x0 _Pragma()
. C++ Builder's Компилятор Windows 32bit не поддерживает ни один из них. Однако его Windows 64bit и мобильные компиляторы (все они основаны на clang и поддержке C++ 11) DO поддерживают оба из них. Таким образом, вы можете добавить поддержку для этих компиляторов макросов, как это:
#if defined(__BORLANDC__)
#if defined(__clang__)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#else
#error Cannot define PACKED macros for this compiler
#endif
#elif defined(_MSC_VER)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#else
#error PACKED macros are not defined for this compiler
#endif
Если вы хотите поддержать C++ Builder Windows 32bit компилятора, вам придется переместить логику в.ч файлы, которые используют #pragma
для него, а затем вы можете #include
те файлы, где это необходимо (по крайней мере, до тех пор пока компилятор не будет обновлен для поддержки лязг/C++ 11 - который Embarcadero в настоящее время работает над):
pack1_begin.h:
#if defined(__BORLANDC__)
#define PACKED_BEGIN
#define PACKED
#define PACKED_END
#pragma pack(push, 1)
#elif defined(_MSC_VER)
#define PACKED_BEGIN __pragma(pack(push, 1))
#define PACKED
#define PACKED_END __pragma(pack(pop))
#elif defined(__GNUC__)
#define PACKED_BEGIN
#define PACKED __attribute__((__packed__))
#define PACKED_END
#else
#error PACKED macros are not defined for this compiler
#endif
pack_end.h:
#if defined(__BORLANDC__)
#pragma pack(pop)
#endif
Тогда вы можете сделать это:
#include "pack1_begin.h"
PACKED_BEGIN
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
PACKED_END
#include "pack_end.h"
Если принять этот подход, вы можете просто бросить PACKED_BEGIN
/PACKED_END
вообще:
pack1_begin.h:
#if defined(__BORLANDC__) || defined(_MSC_VER)
#define PACKED
#pragma pack(push, 1)
#elif defined(__GNUC__)
#define PACKED __attribute__((__packed__))
#else
#error PACKED macro is not defined for this compiler
#endif
pack_end.h:
#if defined(__BORLANDC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#include "pack1_begin.h"
struct PACKED {
short someSampleShort;
char sampleByte;
int sampleInteger;
} structType_t;
#include "pack_end.h"
Вы могут по-прежнему использовать '#include 'packed_begin.h" и '#include" pa cked_end.h "(без охранников) – Jarod42
Спасибо за ваш комментарий, но я не могу использовать #include в макросе, потому что borland этого не поддерживает. Я мог переписать библиотеку, но я надеялся на возможность с макросами – user2358582
@ user2358582 И хорошо, что это не должно быть, это не законный C++. Я считаю, что Jarod означал, что вы можете * заменить * макрокоманды на это. – Angew