COBOL调用Windows API GetSystemInfo()时SYSTEM_INFO结构数据异常求助
解决COBOL调用GetSystemInfo()时SYSTEM_INFO结构数据错误的问题
你猜的没错,问题根源确实出在dwActiveProcessorMask的类型定义上——这个成员的类型适配错误直接导致了整个SYSTEM_INFO结构的内存布局错位,API写入数据时自然无法正确填充所有字段。
问题分析
Windows API里的SYSTEM_INFO结构中,dwActiveProcessorMask的实际类型是ULONG_PTR:这是一个与指针宽度一致的无符号整数(32位系统下是32位,64位系统下是64位)。而你的代码里犯了两个关键错误:
- 把
DWORD-PTR定义成了POINTER类型(指针类型),但ULONG_PTR是无符号整数,不是指针; - 基础类型
DWORD用了有符号的pic 9(9) comp-5,但Windows API的DWORD是无符号32位整数,有符号定义会导致数值解析错误。
修正步骤与代码示例
下面是修正后的完整代码,我会标注每一处修改的原因:
identification division. program-id. TEST. Environment Division. CONFIGURATION SECTION. special-names. call-convention 74 is WinAPI. working-storage section. ! 修正:将DWORD定义为无符号32位整数,匹配Windows API的DWORD类型 01 DWORD pic 9(9) comp-5 unsigned value 0 typedef. ! 修正:将WORD定义为无符号16位整数 01 WORD pic 9(5) comp-5 unsigned value 0 typedef. 01 LPVOID POINTER typedef. ! 新增:定义ULONG_PTR,匹配API中dwActiveProcessorMask的类型(指针宽度的无符号整数) 01 ULONG-PTR POINTER typedef unsigned. ! 修正SYSTEM_INFO结构,替换错误的DWORD-PTR为ULONG_PTR 01 SYSTEM-INFO. 05 dwOemId DWORD. 05 wProcessorArchitecture WORD. 05 wReserved WORD. 05 dwPageSize DWORD. 05 lpMinimumApplicationAddress LPVOID. 05 lpMaximumApplicationAddress LPVOID. 05 dwActiveProcessorMask ULONG-PTR. ! 这里是核心修正 05 dwNumberOfProcessors DWORD. 05 dwProcessorType DWORD. 05 dwAllocationGranularity DWORD. 05 wProcessorLevel WORD. 05 wProcessorRevision WORD. linkage section. ! 现在不需要LS-DWORD-PTR了,直接用ULONG-PTR类型访问dwActiveProcessorMask即可 01 LS-ULONG-PTR ULONG-PTR. procedure division WinApi. 100-MAIN SECTION. call winapi "GetSystemInfo" using by reference System-Info end-call. ! 直接赋值访问,因为ULONG-PTR已经是正确的类型,无需地址转换 move dwActiveProcessorMask to LS-ULONG-PTR. ! 这里可以添加输出逻辑验证结果,比如显示dwNumberOfProcessors等字段 stop run.
关键修改说明
- 无符号基础类型:把
DWORD和WORD改成无符号类型,避免有符号整数的数值溢出或解析错误; - ULONG_PTR类型定义:新增
ULONG-PTR作为指针宽度的无符号整数类型,完全匹配Windows API中dwActiveProcessorMask的要求; - 修正结构成员类型:将
dwActiveProcessorMask从DWORD-PTR(指针类型)改为ULONG-PTR(无符号整数类型),保证结构的内存偏移完全符合API的要求; - 简化访问逻辑:现在可以直接访问
dwActiveProcessorMask的值,不需要再通过地址转换,避免额外的类型错误。
测试建议
分别在32位和64位编译环境下测试代码,验证dwNumberOfProcessors、dwPageSize等字段是否能正确获取,同时检查dwActiveProcessorMask的数值是否符合当前系统的处理器掩码(比如4核系统可能返回0xF)。
内容的提问来源于stack exchange,提问作者Kellie Fitton
相关产品推荐
相关产品推荐

