Home

Awesome

zigwin32gen

Generates Zig bindings for Win32 using https://github.com/marlersoft/win32json. If you just want to use the bindings, see https://github.com/marlersoft/zigwin32.

How to generate the Windows Zig bindings

Download zig, currently tested on version: 0.12.0-dev.2701+d18f52197

First, clone the zigwin32 repo from the root of this repository to provide a location for the generated files:

git clone https://github.com/marlersoft/zigwin32

Then run the following command to generate the latest bindings:

zig build

On the first run, running this command will provide an error message saying that the win32json dependency is missing, and will provide you with a git command to clone it and checkout the expected version.

Once the build task completes, you can view your generated code in the zigwin32 subrepository that you cloned earlier.

win32json vs C/C++ Win32 SDK

The win32metadata project from which win32json is generated does not expose the exact same interface as the classic C/C++ header files did. One thing I'd like is to support is to be able to take a Windows C/C++ example and port it to Zig without changing any names/types or the way it interfaces with the Windows API. To support this I'll need to:

For example, intead of DWORD or UINT32, I would generate u32. Instead of field names with hungarian notation, I would generate them with snake case. These would only be cosmetic changes, where it would look more natural to use the Windows API directly alongside other Zig APIs. The bigger advantage to this is not having to track all the different ways to declare the same type, for example, a developer having to know that DWORD, UINT32, ULONG, UINT are all the same as u32.

extra.txt

This file contains extra metadata, namely,

"Union Pointers" are pointers that in addition to actual pointer values also accept special reserved values that aren't actually pointers.

It's important for Zig to know when this is the case because Zig inserts runtime alignment checks when casting non-pointer values to pointers. To address this, anytime a pointer type is actually a "union pointer", we annotate that pointer type with align(1) to ellide this runtime alignment check. Note that the reason for using align(1) instead of a union type is because modifying a parameter type to be a union instead of a pointer can modify the ABI. See https://github.com/dotnet/coreclr/pull/23974#issuecomment-482961995 for an example of this.

See Issue "CreateWindowEx lpClassName union": https://github.com/microsoft/win32metadata/issues/623

We also add include extra information about which pointers are "not null". By default, all pointer types in the metadata are treated as being "optional" (i.e. ?*T). We can override this default by providing a "NotNull" modifier in extra.txt.

The "NotNull" modifier is a sequence of 0/1 flags. Each flag modifies a pointer in the type to be "non-optional". For example, consider the type ?*?*?*T. The integer value 0 would leave the type unmodified. The modifier 1 would modify the first pointer in the type to make it *?*?*T. The modifier 10 would modify the second pointer in the type to become ?**?*T. The integer value 111 would modify all 3 pointer types to become ***T.