正如您所说,C++Builder 不支持宏内部的预处理器语句。 Embarcadero 网站上对此进行了记录:
#定义 (C++) http://docwiki.embarcadero.com/RADStudio/XE8/en/Define
在每个单独的宏扩展之后,将对新扩展的文本进行进一步扫描。这允许嵌套宏的可能性:扩展文本可以包含需要替换的宏标识符。但是,如果宏扩展为看起来像预处理指令的内容,则预处理器将无法识别该指令。
这样做的原因是因为#
宏内部的字符保留给预处理器字符串化运算符.
一些编译器,包括 MSVC,通过以下方式绕过了这个限制__pragma()
编译器扩展,或 C99/C++x0_Pragma()
扩大。 C++Builder 的视窗32位编译器不支持其中任何一个。然而,其视窗 64 位 and mobile编译器(全部基于 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视窗32位编译器,您必须将逻辑移动到使用的 .h 文件中#pragma
为它,然后你可以#include
这些文件在需要的地方(至少在编译器更新为支持 clang/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"