Updated architecture.md and removed stale design document.

This commit is contained in:
Mike Battista 2023-05-05 10:29:00 -07:00
Родитель 4e6e7451f8
Коммит c69b582cb7
2 изменённых файлов: 24 добавлений и 50 удалений

Просмотреть файл

@ -1,49 +0,0 @@
# Win32 Metadata SDK Overview
## Goals
Provide the public surface area of the Win32 SDK in a language-agnostic format that can be projected into other languages such as modern C++, C# and Rust.
## Motivation
The public API surface area of Win32 is described with C/C++ headers. These are not easily parseable for those who want to make an interop layer from different languages to Win32 APIs. As other languages gain in popularity, we would like to meet developers where they're at and provide a way for them to make use of Win32 APIs in languages other than C/C++. Once we are able to describe the Win32 API surface in metadata, we can create language projections so developers can call Win32 APIs from those languages.
## Metadata Format
### ECMA-335
We have chosen to use [ECMA-335](http://www.ecma-international.org/publications/standards/Ecma-335.htm) to represent Win32 metdata. ECMA-335 is the binary format used for .NET binaries.
#### Pros
- This format is currently used for WinRT metadata (.winmd files) and is already consumed by [C++/WinRT](https://github.com/Microsoft/cppwinrt) and [Rust WinRT](https://github.com/Microsoft/cppwinrt) in order to project WinRT APIs. These two projects already have tooling to parse and consume ECMA-335 binaries, so consuming ECMA-335 metadata for Win32 APIs should be less work than using a completely new format.
- Managed code was originally designed to work well with Win32 interop, so most of the Win32 concepts we need expressed in metadata should already exist.
- It is trivial to write C# code that uses reflection to examine the metadata from a C# binary.
#### Cons
- ECMA-335 can't express all C constructs, such as bit fields or anonymous structs. We do our best to emit metadata that can be intepreted back to what the original headers intended.
## Architecture
### Scraper/Emitter: ClangSharp
A tool that can accurately scrape Win32 C/C++ headers for the information needed to construct language-agnostic metadata. It should be able to capture:
- API functions and which DLL exports each function
- structs, including unions and embedded structs, packing information, and bit fields
- Function pointers for APIs that use callback semantics
- enums
- In/out/optional semantics (like SAL) for each parameter
### Metadata emitter
The emitter will take the output of the scraper and emit metadata. Currently there is information we need emitted that isn't in the current Win32 headers. This could be added to the headers in the future, but for now the emitter will need additional input:
- Which functions call `SetLastError`.
- Which parameters and fields that represent Win32 resources (e.g. handles and GDI objects) are logically grouped together and which Win32 function can be called to release them (e.g. file handles vs. registry handles vs. GDI objects).
- Many functions use a non-enum type, like a DWORD, and then use many #define statements to describe the possible values that function can recognize for tht parameter.
### Language projections
We will need individual tools that turn the ABI represented in metadata into language-specific projections.
- Modern C++ -- someone might ask, why would you need this when you can just use the C-style APIs? This projection could use RAII types for Win32 resources (e.g. handles and GDI objects). It could also potentially use exceptions by interpreting the C-style return codes.
- Rust
- C# -- we would expect this to use SafeHandle abstractions for Win32 resources (e.g. handles and GDI objects), string objects for strings instead of char*/wchar*, etc.

Просмотреть файл

@ -4,8 +4,12 @@ The [Scraper](#scraper) layer is responsible for traversing header files and gen
The [Emitter](#emitter) layer is responsible for traversing the generated C# files and generating Windows.Win32.winmd.
The [WinmdGenerator](#winmdgenerator) packages the Scraper and Emitter tooling into an [MSBuild project SDK](https://learn.microsoft.com/visualstudio/msbuild/how-to-use-project-sdk) that acts as the interface for converting C/C++ projects to winmds for use with language projections.
## Scraper
The Scraper layer is responsible for traversing header files and generating C# files.
### ClangSharp
[ClangSharp](https://github.com/dotnet/ClangSharp) traverses header files as defined within [Partitions](../generation/WinSDK/Partitions) and generates C# files within [generated](../generation/WinSDK/obj/generated).
@ -28,6 +32,17 @@ Project-specific settings are included within [ConstantsScraper.settings.rsp](..
## Emitter
The Emitter layer is responsible for traversing the generated C# files and generating Windows.Win32.winmd.
[ECMA-335](https://www.ecma-international.org/publications-and-standards/standards/ecma-335/) defines the format of winmd files. ECMA-335 is the binary format used by .NET binaries.
* WinRT winmd files use this format
* Many Win32 concepts already supported from .NET interop
* Reflection-based APIs provide a simple interface for parsing the metadata directly
* Reflection-based APIs provide a simple means to convert winmd to other formats like JSON
The Emitter layer augments ECMA-335 by applying additional patterns and custom attributes that allow language projections to understand Win32-specific semantics and provide an improved developer experience. See [PROJECTIONS.md](projections.md).
### ClangSharpSourceCompilation
This class orchestrates the manipulation and compilation of the generated C# files.
@ -50,4 +65,12 @@ This class handles merging C# files from multiple architectures to identify arch
### ClangSharpSourceWinmdGenerator
This class walks the final C# abstract syntax trees (AST) and writes each node to Windows.Win32.winmd.
This class walks the final C# abstract syntax trees (AST) and writes each node to Windows.Win32.winmd.
## WinmdGenerator
The WinmdGenerator packages the Scraper and Emitter tooling into an [MSBuild project SDK](https://learn.microsoft.com/visualstudio/msbuild/how-to-use-project-sdk) that acts as the interface for converting C/C++ projects to winmds for use with language projections.
The WinmdGenerator tooling is published to nuget.org as [Microsoft.Windows.WinmdGenerator](https://www.nuget.org/packages/Microsoft.Windows.WinmdGenerator/). As an MSBuild project SDK, it enables a no-code project file based configuration interface for generating winmd files from arbitrary C/C++ projects.
[win32metadata](https://github.com/microsoft/win32metadata/blob/main/generation/WinSDK/Windows.Win32.proj) and [wdkmetadata](https://github.com/microsoft/wdkmetadata/blob/main/generation/WDK/Windows.Wdk.proj) both demonstrate WinmdGenerator project files. The WinmdGenerator version can be controlled as described [here](https://learn.microsoft.com/visualstudio/msbuild/how-to-use-project-sdk#reference-a-project-sdk).