Windows has a huge API surface. This opens the question of, what is the purpose of std lib windows API bindings?
Is it...
In this proposal I am advocating for (1). I also think that (2) would be reasonable. I agree with @LemonBoy here that (3) is not reasonable.
By bindings are we talking just the function signatures, or wrappings with zig errors and such?
The latter obviously being a lot more work.
My vote for 2
My vote is for (2) too, if the conversion process can be completely automated it's even better.
By bindings are we talking just the function signatures, or wrappings with zig errors and such?
The latter obviously being a lot more work.
If we are talking the former, most of the work could be automated, with the caveat being that deciding which pointers are nullable will likely have to be done by a human.
(3) it should contain preferred API's which excludes non thread safe functions and deprecated apis and possibly apis are not present in lowest supported windows version (win 8.1?)
and possibly apis are not present in lowest supported windows version (win 8.1?)
I'm not aware of microsoft ever removing api functions (at least in the last 20 years) - they're very against this.
Personally I'm against 3 primarily because it will spawn endless avoidable discussion on what does and doesn't constitute as an excludable function.
There is also that if you're using winapi instead of the rest of the standard library you're likely doing things very wrong in the first place (...let's assume we're at 1.0 and the standard library is all good and covers all common use cases).
Another thing to add to this question: how to we deal with multiple versions of windows, which have differing sets of functions? (related: #1907)
2
@Sobeston they do not remove apis, but they add them.
I vote for (1) as it would fit the Zig spirit of "not doing too much".
std should only use a minimum set of APIs and if a user needs the full WinAPI including windows, fibers, ... he/she should import a WinAPI package.
This reduces the maintenance surface of std and the core of the language is kept small
I think 1 + 2... which is 3 I guess.
I think the options could be rewritten as the following:
Option 1 seems the most sustainable in the long run.
@Sobeston IIUC this is about bindings only, not wrapping them in idiomatic Zig.
I fail to see how option (1) is different from (3) in practice.
The standard library will always need to provide OS abstraction, and as such will need the necessary bindings to windows api. Unless they're made inaccessible to the users and we force them to use the third-party windows package, this is effectively an opinionated subset of the API.
So I'd vote for 2.
@Sahnvour if we're just talking bindings then that's pretty much as easy as getting all the function signatures, so I vote for 2. I write stuff with the windows API, and this would be extremely convenient. It also means that there isn't much room for disagreement on what functions should be there. Would be happy to help fill that out.
As for what DLLs, I think Kernel32, NtDll, User32 are the most important.
And versioning, targeting 8.1 is a good idea.
I think std should depend on bare minimum (so option 1), but since there is an obvious need to interact with OS, there should be another project, some library with complete win32 APIs, probably with thin Zig-way wrappers. Rust and Delphi follow this path more or less successfully, and there is http://pinvoke.net for .Net. I actually hate .Net CRL approach, because it's not one-to-one mapping, but some leaking abstraction, so pinvoke.net code often replaces CLR, not just complements it.
I'd actually, highly prefer to have thin wrappers, over no wrappers. At least, because memory management strategies (who's the owner of a buffer, which function frees memory, can a buffer be moved in memory between related calls) vary wildly in win32.
Regarding version. It's not even about functions and their prototypes. TCP_FASTOPEN is available since some version (1607, but not the point) of Windows 10. Such new flags if used on older Windows versions often generate ERROR_INVALID_PARAMETER errors. Should every application interested in TCP_FASTOPEN implement own fallback logic, or should thin wrapper become a little thicker?
I'd say 1, but I'm not sure what 2 means. I guess it's a little bit more than a @cImport() would generate, but then if you wrap around it you'll have to document all the things you did as well. So... somehow that doesn't feel like the right thing to do for a language.
Def. 2
How about the renaming of basic win32 types? I can see a lot of benefit in doing that, with the drawback that reading the win32 C docs might get a little more awkward:
I see from the current bindings that sometimes types like LPCWSTR are renamed to [*:0]const u16 and such. This is probably necessary in some cases, as the type does not otherwise specify if the string is null-terminated. MultiByteToWideChar takes a LPWSTR plus length separately for example.
Should types like INT32 use i32 instead?
Should types like UINT use u32 or perhaps c_uint instead? Note that ULONG is always 32 bits on Windows but long 64 bits on most 64-bit Linuxes, so IMHO this would make the functions a lot less confusing to use.
Should DWORD and such use u32 instead? Can there be an instance where knowing that a function takes a DWORD as opposed to an UINT is useful information?
Sometimes win32 functions do awful hacks like in UnregisterClassW, where if the u16 string argument is small enough it is treated as an ATOM id instead. Since the ATOM id isn't necessarily divisible by 2 and as such not casteable to an [*:0]u16, there is no way for safety-checked Zig to use this feature. Could we replace these arguments with a union wrapper? (would that even work with stdcall?)
Most helpful comment
I vote for (1) as it would fit the Zig spirit of "not doing too much".
stdshould only use a minimum set of APIs and if a user needs the full WinAPI including windows, fibers, ... he/she should import a WinAPI package.This reduces the maintenance surface of
stdand the core of the language is kept small