Mal*_*glu 46 c c++ gcc visual-c++ data-structures
对于某些编译器,有一个结构的打包说明符,例如::
RealView ARM compiler has "__packed" Gnu C Compiler has "__attribute__ ((__packed__))" Visual C++ has no equivalent, it only has the "#pragma pack(1)"
我需要一些我可以放入结构定义的东西.
任何信息/黑客/建议?TIA ...
Ste*_*eph 75
您可以为GNU gcc定义这样的PACK
#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif
#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#endif
Run Code Online (Sandbox Code Playgroud)
和Visual C++一样:
PACK(struct myStruct
{
int a;
int b;
});
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif
#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#endif
Run Code Online (Sandbox Code Playgroud)
Ste*_*sop 28
我不知道这样做的光滑方式,但你可能会做一些可怕的事情:
#include "packed.h"
struct Foo { /* members go here */ } PACKED;
#include "endpacked.h"
Run Code Online (Sandbox Code Playgroud)
那么对于MSVC,packed.h:
#define PACKED
#pragma pack(push,1)
Run Code Online (Sandbox Code Playgroud)
endpacked.h
#pragma pack(pop)
#undef PACKED
Run Code Online (Sandbox Code Playgroud)
对于gcc,packed.h:
#define PACKED __attribute__ ((__packed__))
Run Code Online (Sandbox Code Playgroud)
endpacked.h:
#undef PACKED
Run Code Online (Sandbox Code Playgroud)
从根本上说,包装过于依赖平台.假设您的压缩结构中包含8位字段,并考虑一些具有16位字节的系统.它只能通过打包来形成一个表示数据的结构 - 你必须知道在两个系统之间传输时如何将8位字节转换为16位字节.16位机器上的结构可能需要位域,在这种情况下,您必须知道实现如何实现它们.
因此,如果代码通常是可移植的,您可能只需要在头文件的特定于平台的部分中定义所需的任何打包结构.或者更确切地说,构造您的代码,以便未来的端口可以做到这一点,如果必须的话.
Sam*_*sen 15
我知道这个问题现在已经过时了,但我相信有一个比之前发布的更好的解决方案.毕竟,可以将pragma放在结构声明行中的MSVC案例中.考虑以下:
#ifdef _MSC_VER
# define PACKED_STRUCT(name) \
__pragma(pack(push, 1)) struct name __pragma(pack(pop))
#elif defined(__GNUC__)
# define PACKED_STRUCT(name) struct __attribute__((packed)) name
#endif
Run Code Online (Sandbox Code Playgroud)
然后就可以这样使用:
typedef PACKED_STRUCT() { short a; int b } my_struct_t;
PACKED_STRUCT(my_other_struct) { short a; int b };
Run Code Online (Sandbox Code Playgroud)
等等
这里的关键是__pragma的使用只需要围绕struct的声明行.如果给出一个结构名称,则需要包含结构名称,因此该名称是宏的参数.当然,这很容易扩展到enum/class,我将把它作为练习留给读者!
包文档MSDN页面上的测试程序可用于验证这一点.
编辑
在我的测试中,我在Windows上使用了英特尔编译器.使用icl.exe这种方法没有问题,但使用Microsoft编译器(cl.exe),它没有(使用2010和2013测试).
你可以反过来做,因为GCC支持VC++包相关的pragma.看这里了解更多信息.
提取...
为了与Microsoft Windows编译器兼容,GCC支持一组
#pragma
指令,这些指令可以更改随后定义的结构(除了零宽度位域除外),联合和类的成员的最大对齐.下面的n值始终需要是2的小幂,并以字节为单位指定新的对齐方式.
#pragma pack(n)
只需设置新的对齐方式.
#pragma pack()
将对齐设置为编译开始时生效的对齐(另请参阅命令行选项,-fpack-struct[=<n>]
请参阅代码选项选项).
#pragma pack(push[,n])
将当前对齐设置推送到内部堆栈,然后可选地设置新对齐.
#pragma pack(pop)
将对齐设置恢复为保存在内部堆栈顶部的设置(并删除该堆栈条目).注意,
#pragma pack([n])
这不会影响这个内部堆栈; 因此可以#pragma pack(push)
跟随多个#pragma pack(n)
实例并由单个最终确定#pragma pack(pop)
.一些目标,例如i386和powerpc,支持将
ms_struct
#pragma
结构列为记录的结构__attribute__((ms_struct))
.
#pragma ms_struct on
打开声明的结构的布局.
#pragma ms_struct off
关闭声明的结构的布局.
#pragma ms_struct reset
回到默认布局.
根据您需要支持的编译器,另一个解决方案是注意到GCC至少从4.0.4版本开始支持Microsoft样式的打包pragma(在线文档可从gnu.org获得,版本为3.4.6和4.0.4) - 前者没有描述pragma,后者也是如此.这允许您#pragma pack(push,1)
在结构定义之前和定义#pragma pack(pop)
之后使用,它将在任一个中编译.
归档时间: |
|
查看次数: |
62882 次 |
最近记录: |