Windows:优先使用原生 API 而非 Win32
| 2026-02-13
Table of Contents
摘要
这篇发布于 2026 年 2 月 5 日的 Zig 语言 Issues(编号 #31131),标题为“Windows: Prefer the Native API over Win32”,详细阐述了 Zig 项目在 Windows 平台上的一项重要技术策略调整:即优先使用更底层的 Native API(由 ntdll.dll 导出),而不是传统的 Win32 API(由 kernel32.dll 等导出)。
1. 核心主张:为何要“弃用”Win32,转向 Native?
作者并非 Zig 核心成员,但深度参与了相关工作。他提出,现代 Windows 的 Win32 API 本质上是构建于 Native API 之上的一个“子系统”。Native API 是内核直接提供的、更接近底层的接口。Zig 选择优先使用 Native API,主要基于以下四大优势:
- 性能:绕过 Win32 这一软件层,直接与内核交互,减少调用开销。
- 能力:Native API 暴露了更多 Win32 未提供的功能和信息(例如,更丰富的文件变化通知
NtNotifyChangeDirectoryFileEx)。 - 依赖:减少对
kernel32.dll等子系统 DLL 的依赖,有助于生成更小、更精简的可执行文件,并能在 Windows 启动早期运行。 - 灵活性与错误处理:
- Native API 直接返回丰富的
NTSTATUS错误码,而 Win32 通常只返回BOOL,失败后还需调用GetLastError查询,多了一层转换。 - 使用的数据类型(如时间
LARGE_INTEGER、权限掩码ACCESS_MASK)更现代、更统一,更易于与 Zig 的语言特性(如打包结构体)结合。
- Native API 直接返回丰富的
2. 潜在风险与挑战
作者也坦诚地列出了使用 Native API 的固有风险,这也是为什么这是一个需要审慎决策的策略:
- 缺乏文档:Native API 大部分未公开,学习和使用难度远高于有完善文档的 Win32 API。
- 变更风险:作为“内部实现细节”,微软理论上可以随时修改它而不做通知。不过作者指出,实践中这类破坏性变更非常罕见,因为微软自身的大量工具也依赖它。
- 兼容性问题:可能影响程序在旧版 Windows(Zig 官方只支持 Win10/11 及对应服务器版)或 Wine 上的运行。
- 安全软件误报:调用底层、非标准 API 的行为可能更容易被安全软件标记为可疑。
3. 具体实践:哪些该换,哪些该留?
该策略并非一刀切。作者详细划分了替换的界限:
| 类别 | 示例 | 说明 |
|---|---|---|
| 可替换的(“公平游戏”) | ABI 兼容的转发器(如 ReleaseSRWLockExclusive 直接转发给 RtlReleaseSRWLockExclusive)、简单包装器(如 CopySid)、组合 API(如 CreateIoCompletionPort) | 这些 Win32 函数本质上是 Native API 的简单封装,可以直接替换以获得更清晰的错误处理和性能提升。 |
| 过于复杂,暂不替换 | 控制台 API(已在讨论过程中被重写)、Winsock API、动态库加载、进程创建(NtCreateUserProcess 因需与 csrss.exe 复杂交互而异常脆弱) | 这些领域要么实现过于复杂,要么与 Windows 子系统的深层机制绑定,使用 Native API 的收益远低于风险和复杂度。 |
4. 对常见质疑的回应
议题最后,作者以问答形式回应了社区可能存在的疑虑,展现了 Zig 团队务实的态度:
- 问:如果我直接用了
std.os.windows.kernel32里的函数,它们被移除了怎么办?- 答: 会编译报错。建议需要稳定 Win32 调用的用户,将函数定义拷贝到自己项目中,或使用专门的绑定库(如
zigwin32)。
- 答: 会编译报错。建议需要稳定 Win32 调用的用户,将函数定义拷贝到自己项目中,或使用专门的绑定库(如
- 问:这会影响旧版 Windows 兼容性吗?
- 答: 会的。但 Zig 标准库的目标平台是基于开发者能支持的最新稳定版本(Win10/11)。追求极致向后兼容的用户应直接调用 Win32。
- 问:在 Wine 上出问题了怎么办?
- 答: 我们视其为 Wine 的 bug。除非严重影响 CI 测试,否则不会主动为 Wine 添加特殊处理。
- 问:微软更改 Native API 怎么办?
- 答: 首先,Native API 的设计(如信息类枚举 + 可变长结构)本身就具备很强的扩展性,旧 API 极少被移除,只会增加新版本。其次,如果有变更,Zig 标准库会负责处理,用户代码无需感知。
5. 总结
这篇 Issues 不仅仅是一个技术讨论,它清晰地阐述了 Zig 在系统编程语言定位下的一个具体决策:为了追求更高的性能、更强的能力和更简洁的代码,宁愿承担使用文档不全的 API 的风险,也要尽可能地接近操作系统底层。
它展示了 Zig 团队在理想目标(性能、控制力)与现实挑战(兼容性、稳定性、文档缺失)之间所做的精细权衡。对于 Zig 开发者而言,这意味着在 Windows 平台上编写代码时,可以期待标准库提供更底层、更强大的能力,但也需要理解这种选择所带来的边界(如官方支持的 Windows 版本范围)。
Works cited
- Windows: Prefer the Native API over Win32 · Issue #31131 · ziglang/zig - Codeberg, accessed 2026 年 2 月 6 日。