C++ 结构体大小与 C++/CLI 中的结构体大小不相等?

5
我的问题涉及标题中提到的问题。
我在头文件中有一个简单的结构体,如下所示:
typedef struct
{
    WORD FileType;          // File ID (0x7000)
    WORD HeaderSize;        // Size of this file header in Bytes
    WORD HeaderVersion;     // yy.y
    ULONG FileSize;         // Size of the whole file in Bytes
    WORD ImageHeaderSize;   // Size of the image header in Bytes
    WORD ULX, ULY, BRX, BRY;// bounding rectangle of the image
    WORD NrOfFrames;        // self explanatory
    WORD Correction;        // 0 = none, 1 = offset, 2 = gain, 4 = bad pixel, (ored)
    double IntegrationTime; // frame time in microseconds
    WORD TypeOfNumbers;     // short, long integer, float, signed/unsigned, inverted, 
                            // fault map, offset/gain correction data, badpixel correction data
    BYTE x[WINRESTSIZE];        // fill up to 68 byte
} WinHeaderType;

如果我在C控制台应用程序中调用sizeof(WinHeaderType),我会得到68,但如果我在C++/CLI中使用相同的参数调用相同的函数,则会得到80。
有人能解释一下这种行为吗?
我对C++/CLI非常陌生,事实上我以前从未使用过它(几天前才开始),但我需要为.NET应用程序创建一个dll。
由于这是我的第一篇帖子,希望我没有违反任何论坛规则。
问候, Mo
[编辑] 它变得越来越奇怪了...

第一行:C控制台应用程序的输出

第二行,第一列:我编写的C/C++控制台应用程序,用于检查数据类型大小。

第二行,第二列:我编写的C++/CLI控制台应用程序,用于检查数据类型大小。

第一个应用程序的源代码:http://fbe.am/sId

最后两个应用程序的项目文件:http://fbe.am/sIf

有人能解释一下这是什么?!


也许你的控制台应用程序没有字段填充?也许 WINRESTSIZE 不同?也许 WORD 不同?最重要的是,C++/CLI 不是 C++。 - Some programmer dude
请展示完整的程序。我们无法确定宏定义是什么。包括完整的C语言程序和完整的C++/CLI程序。 - David Heffernan
C控制台应用程序使用与C++/CLI DLL相同的头文件。 我知道C++/CLI不是C++,但是CLI已经集成了本地数据类型,因为它使用了C++(?)或移植的C++(?)头文件。 我没有检查填充问题,但是使用C++/CLI不应该得到相同的结果吗?我在C++/CLI中调用C函数和本机(非托管)数据类型,而且当结构成员来自具有固定大小的数字性质时,编译器如何优化结构成员的大小...?也许我在胡说八道,如果我错了,我会感激你们纠正我:D - Oli_Mo
@David Heffernan:http://fbe.am/sIc(CLI-不可编译,请确保您记得需要Console.rar中的“Acq.h”) http://fbe.am/sId(C++控制台应用程序-可编译) 请不要因为CLI代码而认为我是个糟糕的程序员, 我知道它看起来很糟糕,但我非常绝望, 所以我尝试了地球上几乎所有的方法(像法师一样施法)来使它正常运行。 - Oli_Mo
请问能否提供问题中的两个程序。您需要制作SSCCEs。我们只需要最短的程序。它声明类型并打印大小。 - David Heffernan
我已经发布了第一个程序,但是我无法发布第二个程序的完整源代码,因为我在法律上不被允许这样做。 在两个应用程序中,数据类型都在minwindef.h中定义。 所以它们的大小完全相同...! 还有一个数据类型的速查表[链接]http://wuxuesong.files.wordpress.com/2010/03/c-cli-cheat-sheet.pdf 我也通过编程方式检查了它们的大小...全部相同。 - Oli_Mo
2个回答

3

使用默认的打包规则(/Zp8),该结构包含12字节的填充以使成员对齐。这应该足以解释68和80之间的差异。您需要消除填充,在MSVC编译器中使用#pragma pack

#pragma pack(push, 1)
typedef struct {
   // .. etc
} WinHeaderType;
#pragma pack(pop)

太棒了 <3 谢谢,就这样吧。但是为什么没有像 Pascal 中的 "packed record" 那样的关键字呢?我觉得使用 pragma 注释来实现这个选项非常费力。 - Oli_Mo
1
C和C++编程语言对于那些会使代码运行变慢的关键字不是很依赖。对齐是非常重要的,如果读取一个对齐不正确的double类型的数据,在友好的处理器上可能会慢三倍,在不友好的处理器上则可能会慢数百倍。 - Hans Passant
哇,好的,知道了。非常感谢您提供的信息:D - Oli_Mo

0

这很可能与 WORD 的定义在两种情况下不同有关。 BYTE、WORD 和 ULONG 不是本地的 C++ 类型,因此请检查它们在哪里/如何定义。

BYTE 可能是单个字符。 ULONG 可能是无符号长整型。 但在您的情况下,WORD 可能是不同的。


我编辑了我的问题,添加了一张图片、源代码和项目文件。如果你看这张图片,你会发现数据类型在其他C语言中并没有什么不同。 - Oli_Mo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接