Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

retrowin32,拆分成多个部分

Posted on 2025-05-26

循环.png

这篇文章是retrowin32 系列文章的一部分。

Rust 编译器并行编译代码。但缓存的单位是crate——一个比模块更大的概念,它可能相当于 C 语言中的库或 JS 语言中的包。一个典型的程序就是一个单独的 crate。这意味着每次运行编译器时,它都会从头开始编译所有代码。为了提高构建性能,你可以将程序拆分成多个 crate,希望每次编译时都能重用未修改的 crate。

retrowin32 已经被划分成几个 crate,并遵循一些明显的界限。x86 模拟器、win32 实现、原生目标和 Web 目标各自独立。但 win32 实现和底层系统必然会非常复杂,因为(除其他因素外)x86 代码会调用 win32 函数,而这些函数可能需要回调到 x86 代码中。

这意味着对 win32 实现的任何更改都会重新编译大量代码。这篇文章将介绍我如何进一步拆分,每个 Windows 库对应一个 crate。retrowin32 现在拥有像builtin-gdi32和builtin-ddraw这样的 crate,它们实现了 Windows 的这些部分,并且它们现在可以(大部分情况下)并行编译和缓存。

大循环

深入研究后,会发现有一个神对象Machine ,它保存着 CPU 模拟器(例如寄存器状态)以及系统的其他部分(例如内存和内核状态)。当Machine模拟执行 win32 函数调用时(如syscalls 文章中所述),它会将自身传递给目标系统,从而使其能够获取系统状态,并可能回调以进行进一步的模拟。

例如,Windows CreateWindow API 创建一个窗口,作为该过程的一部分,它同步“发送” WM_CREATE消息,这具体意味着在CreateWindow中我们调用窗口过程并将控制权交还给模拟代码。

循环.png

不同的 crate 之间不能有循环,所以这种循环意味着我们必须把Machine和所有 win32 实现放在一个 crate 里。解决方法就像大多数计算机科学问题一样,就是增加一层抽象。

一个新的共享 crate 定义了一个System trait,它是一个接口,用于表达“win32 函数实现可能需要调用的底层系统中的内容”。它会被传递给 win32 API 并由Machine实现,这样我们就可以将 win32 函数编译为单独的 crate,每个 crate 仅依赖于System的定义。

特质.png

这种布局的一个有趣结果是,只要System接口暴露出某种调用用户代码的方式,win32 实现就不再直接依赖于任何模拟器。你可以设想一个在原生 32 位 x86 上运行的 retrowin32,或者一个允许你将已有源代码的 Windows 程序移植到像winelib这样的非 x86 平台的 retrowin32。

系统状态

我上面提到过, Machine也保存系统状态。例如, gdi32实现了绘图 API,它提供了提供设备上下文句柄的函数。System System启用的新gdi32库可以声明它所需的状态,但我们必须将该状态存储在某个地方。

此外,这些不同的 Windows 库之间存在相互依赖关系。例如,处理窗口和消息传递的user32需要使用gdi32中的代码来实现在窗口上绘图。而实现音频功能的winmm crate 则与这些库无关。

一种显而易见的方法——我想象它在真实的 Windows 中可能有效——是将此状态保存在每个库的静态全局变量中。我想到了一个有点奇怪的解决方案,所以我想把它写下来,看看是否有读者知道它的名字或更好的方法。

重述一下这个问题,有一个核心的Machine类型,它依赖于所有库,并保存着所有程序状态。但我们希望能够独立地构建每个库,并允许它们之间相互依赖,而不是让它们依赖Machine本身。

答案是让破坏衔尾蛇的System特性公开一个动态类型的“通过类型获取我的状态”函数:

 fn state ( & self , id : & std :: any :: TypeId ) -> & dyn std :: any :: Any ;

每个库(例如gdi32 )都可以注册其状态(例如gdi32::State ),并在需要时从系统中获取。这样,像user32这样的库可以调用gdi32 ,并且它们都可以从共享状态对象访问各自的内部状态。

它可能只是多了一个步骤的静态版本。我还不确定我是否喜欢它。

结果

大部分 win32 API 现在都放在单独的 crate 中。(剩下的部分是kernel32 ,它是最底层的部分,需要做更多工作才能拆开。)

以下是涉及这些单独板条箱的构建部分的瀑布图:

板条箱.png

根据xkcd 的说法,这可能不会为我节省总体时间,但至少当我反复骑行时我不必等待那么长时间。

在底部,你可以看到最终的win32 crate,它将所有内容整合在一起。这个版本仍然太慢(可能是因为 kernel32),但比以前好多了!

原文: https://neugierig.org/software/blog/2025/05/retrowin32-split.html

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme