c - 为什么某些 WinAPI 函数需要将结构的大小作为参数传递?

标签 c windows winapi

例如,考虑SendInput。签名看起来像这样:

UINT WINAPI SendInput(
  _In_ UINT    nInputs,
  _In_ LPINPUT pInputs,
  _In_ int     cbSize
);

文档说:

cbSize [in] Type: int The size, in bytes, of an INPUT structure. If cbSize is not the size of an INPUT structure, the function fails.

既然函数已经使用了 INPUT 结构(并且可能对它的各个字段做了一些事情),难道它不应该事先知道结构的大小吗?

我能想到的唯一原因是,这是一种奇怪的向后兼容性技巧,可以使旧库二进制文件与可能在结构末尾引入新字段的新头文件兼容。

最佳答案

这是结构版本控制的一种简单形式。

更高版本的 API 可以在结构末尾添加更多字段,这将改变其大小。为旧版本编写的程序不会在较新的字段中设置值,cbSize 参数将反射(reflect)这一点。该 API 可以检查 cbSize 并了解它真正拥有的结构版本,并在必要时为新字段提供默认值。

另一种方法是定义一个与旧结构有很多共同点的新结构,然后制作一个与旧结构非常相似的新 API。这是大量的代码重复,它使旧程序更难使用更新的 SDK 重新编译并继续工作。

使用大小字段消除了一堆重复代码的需要。这是用 C 语言做事的常用方法,但它的类型安全性较低。

但这也有点危险。如果调用者没有正确设置大小字段或者 API 实现不是很小心,此方案可能会导致访问冲突、读取未初始化的字段或写入超过结构的末尾。

关于c - 为什么某些 WinAPI 函数需要将结构的大小作为参数传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30416191/

相关文章:

c++ - 数组指针算术题

c - DLL:在 Linux for Windows 上使用 MinGW 编译 C 时无法识别文件格式

delphi - Delphi 中透明光标显示错误颜色

winapi - 我怎样才能加快我的代码覆盖率工具?

node.js - 如何从文件路径获取应用程序名称/元数据

c++ - MapViewOfFile 中信号量的最佳方法 - C++

c - C 实现双端队列时出现段错误

c - socket函数中的stream参数和protocol参数有什么区别?

memory - 如何写入加载到 RAM 内存中的共享库代码段?

windows - 在没有安装 ActivePerl 的情况下在 Windows 上使用 perl 脚本?