首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么要在结构中加上结构的大小?

为什么要在结构中加上结构的大小?
EN

Stack Overflow用户
提问于 2014-09-18 07:02:14
回答 2查看 90关注 0票数 0

我第一次开始在Windows上使用SetupAPI,并注意到在调用填充该结构的函数之前,我总是需要将结构的大小放入结构中。例如:

代码语言:javascript
运行
复制
SP_DEVICE_INTERFACE_DATA dintf_data;
dintf_data.cbSize = sizeof(dintf_data);
SetupDiEnumDeviceInterfaces(di, NULL, &GUID_DEVINTERFACE_USB_DEVICE, 0, &dintf_data);

为什么要这么做?

这是一个很好的方式来实现它是他们正在努力实现,还是有更好的方法?

(我能想到的唯一原因是它是处理API版本控制的一种方法。)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-18 07:05:40

是的,你明白了,API版本控制。

操作系统检查传入的大小,以确定正在使用的结构的哪个版本。在为API的新版本添加功能时,会添加字段(永不移除),以增加大小,这样操作系统就可以很容易地知道您使用的是哪个版本。

票数 5
EN

Stack Overflow用户

发布于 2014-09-18 07:17:38

这是一种版本控制方式,以确保向后(和向前!)兼容性。

想象一下,您有一些用于消息框的struct

代码语言:javascript
运行
复制
struct MessageBoxData {
    const char *message;
    const char *caption;
};

您可以将其编译到API中,并使用它显示带有messagecaption的消息框。你很好。

稍后,发布API版本2,它为显示的图标添加了另一个字段:

代码语言:javascript
运行
复制
struct MessageBoxData {
    const char *message;
    const char *caption;
    unsigned char icon;
};

让我们假设元素的顺序不是由编译器神奇地填充或重组的,而且任何程序都可以将这个更复杂的API版本2结构传递给API版本1库,而不会出现问题。

然而,反过来又会发生什么呢?使用针对API版本1编译的程序和API版本2的库。

库将尝试读取icon,这将导致在此struct的有效边界之外读取!

例如,如果尝试使用memcpy()复制内容,可能会以类似的方式出现问题。

为了避免这种情况,Windows通常期望第一个成员定义结构的实际大小。在本例中,您可以创建如下所示:

代码语言:javascript
运行
复制
// Version 1
struct MessageBoxData {
    unsigned int size;
    const char *message;
    const char *caption;
};

// Version 2
struct MessageBoxData {
    unsigned int size;
    const char *message;
    const char *caption;
    unsigned char icon;
};

您可能认为他们可以只在被调用的函数中使用sizeof()。虽然这在理论上是正确的,但它不能解决编译时(库和程序)之间的不同定义的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25906251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档