WinAPI STARTUPINFO 64 位 (QB64) 的字节打包

Posted

技术标签:

【中文标题】WinAPI STARTUPINFO 64 位 (QB64) 的字节打包【英文标题】:Byte packing for WinAPI STARTUPINFO 64 bit (QB64) 【发布时间】:2021-02-11 14:55:24 【问题描述】:

我正在使用 QB64 编程,这是一种允许类似 QBASIC 的语法的编程语言,并被翻译成 C++ 代码并编译。

如果我们想在我们的代码中使用struct,那么我们必须声明它并手动创建它。在 32 位中,没问题,因为它与 WinAPI MSDN 页面匹配并且几乎总是可以工作。然而,对于 64 位,结构具有不同的字节打包,我无法确定 STARTUPINFO struct 的正确打包。

下面是我对struct 的声明,因为它适用于 32 位。我知道 struct 需要 104 个字节,而我目前短 8 个字节;我已确保我的所有变量都与 64 位大小匹配,但我在结构中的某处缺少 8 个字节的填充。知道字节打包和 WinAPI 结构的人可以帮我解决这个问题吗?

Type STARTUPINFO
    cb As Long '4 bytes
    lpReserved As _Offset '4 bytes in 32, 8 in 64
    lpDesktop As _Offset '4 bytes in 32, 8 in 64
    lpTitle As _Offset '4 bytes in 32, 8 in 64
    dwX As Long '4 bytes
    dwY As Long '4 bytes
    dwXSize As Long '4 bytes
    dwYSize As Long '4 bytes
    dwXCountChars As Long '4 bytes
    dwYCountChars As Long '4 bytes
    dwFillAttribute As Long '4 bytes
    dwFlags As Long '4 bytes
    wShowWindow As Integer '2 bytes
    cbReserved2 As Integer '2 bytes
    lpReserved2 As _Offset '4 bytes in 32, 8 in 64
    hStdInput As _Offset '4 bytes in 32, 8 in 64
    hStdOutput As _Offset '4 bytes in 32, 8 in 64
    hStdError As _Offset '4 bytes in 32, 8 in 64
End Type

【问题讨论】:

所有 64 位指针 - 必须为 8 字节 len 并在 8 字节上对齐 - pastebin.com/KqZ8PB7R 使用sizeofoffsetof 并打印出详细信息。 en.cppreference.com/w/cpp/types/offsetof 【参考方案1】:

下面总结了 32 位和 64 位构建中 STARTUPINFOW 结构的字段大小和位置。 (请注意,这些大小和偏移量对于结构的等效 STARTUPINFOA 版本是相同的,用于非 Unicode 构建。)

32 位 Windows(请注意,不需要填充 - 几乎可以肯定是设计使然):

typedef struct _STARTUPINFOW 
    DWORD   cb;             // 4 bytes ->  4 total
    LPWSTR  lpReserved;     // 4           8
    LPWSTR  lpDesktop;      // 4          12
    LPWSTR  lpTitle;        // 4          16
    DWORD   dwX;            // 4          20
    DWORD   dwY;            // 4          24
    DWORD   dwXSize;        // 4          28
    DWORD   dwYSize;        // 4          32
    DWORD   dwXCountChars;  // 4          36
    DWORD   dwYCountChars;  // 4          40
    DWORD   dwFillAttribute;// 4          44
    DWORD   dwFlags;        // 4          48
    WORD    wShowWindow;    // 2          50
    WORD    cbReserved2;    // 2          52
    LPBYTE  lpReserved2;    // 4          56
    HANDLE  hStdInput;      // 4          60
    HANDLE  hStdOutput;     // 4          64
    HANDLE  hStdError;      // 4          68 bytes total
;

64 位 Windows(现在需要填充,因为 8 字节指针应该是 8 字节对齐的):

typedef struct _STARTUPINFOW 
    DWORD   cb;             // 4 bytes ->  4 total
    // 4 b padding to align next pointer:  8
    LPWSTR  lpReserved;     // 8          16
    LPWSTR  lpDesktop;      // 8          24
    LPWSTR  lpTitle;        // 8          32
    DWORD   dwX;            // 4          36
    DWORD   dwY;            // 4          40
    DWORD   dwXSize;        // 4          44
    DWORD   dwYSize;        // 4          48
    DWORD   dwXCountChars;  // 4          52
    DWORD   dwYCountChars;  // 4          56
    DWORD   dwFillAttribute;// 4          60
    DWORD   dwFlags;        // 4          64
    WORD    wShowWindow;    // 2          66
    WORD    cbReserved2;    // 2          68
    // 4 b padding to align next pointer: 72
    LPBYTE  lpReserved2;    // 8          80
    HANDLE  hStdInput;      // 8          88
    HANDLE  hStdOutput;     // 8          96
    HANDLE  hStdError;      // 8          104
;

【讨论】:

另外,感谢您编辑我的帖子以使其更清晰。非常感谢您的帮助!

以上是关于WinAPI STARTUPINFO 64 位 (QB64) 的字节打包的主要内容,如果未能解决你的问题,请参考以下文章

32位 64位 获得进程peb的方法

64 位应用程序上的 Windows HANDLE 范围是多少?

如何在 Win x64 上使用 WinAPI 正确安装虚拟打印机?

用C++语言如何判断你的系统是64位的

在 CreateProcess 之后修改 STARTUPINFO

DWORD WINAPI?stdcall?