Remix.run Logo
pseudohadamard 3 days ago

For people not familiar with Windows development, another name for the NT native API is "the API that pretty much every document on Windows programming tells you not to use". It's like coding to the Linux syscall interface instead of libc.

HexDecOctBin 2 hours ago | parent | next [-]

Linux syscall interface is actually stable and can easily be targeted. It’s BSDs (and Mac OS) that force everyone to link to only libc.

pjmlp 2 hours ago | parent [-]

More like everyone else, Linux kernel is the exception here.

kvemkon 2 hours ago | parent | prev | next [-]

> It's like ...

Considering the level of the API. But it is total opposite comparing a bit deeper. Linux has a famous rule "WE DO NOT BREAK USERSPACE!" e.g. [1].

[1] https://news.ycombinator.com/item?id=44611692

dunder_cat 2 hours ago | parent [-]

One thing that is amusing about the prevalence of advanced anti-cheat in Windows gaming is it's actually causing said API/ABIs to undergo ossification. A good data point is the invention of Syscall User Dispatch^1 on Linux which would allow a program to basically install a syscall handler when they originate from various regions of memory. I do not know how usable this is in practice, admittedly -- but I think the fact it was contributed at all speaks to the growing need.

^1 https://docs.kernel.org/admin-guide/syscall-user-dispatch.ht...

samus an hour ago | parent | prev | next [-]

With the crucial difference that Linux places high value on syscall interface binary compatibility, while the NT native API is not guaranteed to be stable in any way.

A bit more comparable is OpenBSD where applications are very much expected to only use libc wrappers, which threw a wrench into the works for the Go runtime.

eps an hour ago | parent | prev | next [-]

"Every document" notwithstanding, Native API is very widely used in practice and generally considered stable.

If in doubt, try and find examples of its breakage, semantic changes, etc.

nullpoint420 3 hours ago | parent | prev | next [-]

Yeah, I know go has had issues because they subvert libc themselves in similar fashion. I wonder how this will turn out.

wrs 2 hours ago | parent | next [-]

Go backed out of their strategy on MacOS and started using libc (libsystem?), because when Apple says something is internal and may change without notice, they really mean it. It may be a better risk with Microsoft, but it’s still a risk.

lelanthran 34 minutes ago | parent | prev | next [-]

Same way it turned out for Go: they had to walk it back.

LoganDark 2 hours ago | parent | prev [-]

I think they had to revert back to libc on macOS/iOS because those have syscall interfaces that truly are not stable (and golang found that out the hard way). I wonder if they had to do the same on BSDs because of syscall filtering.

samus an hour ago | parent [-]

Indeed, OpenBSD recently added hardening measures and started restricting the generic syscall interface to libc.

pjmlp 2 hours ago | parent | prev | next [-]

Except unlike Linux syscall interface and like almost every other OS out there, ABI compatibility is an accident, not a guarantee.

koakuma-chan 2 hours ago | parent | prev [-]

> It's like coding to the Linux syscall interface instead of libc.

The right thing to do? I don't see why I would want to use libc.

pjmlp 2 hours ago | parent | next [-]

Nope, in UNIX proper syscalls and libc overlap, that is how C and UNIX eventually evolved side by side, in a way one could argue UNIX is C's runtime, and hence why most C deployments also expect some level of compatibility with UNIX/POSIX.

Linux is the exception offering its guts to userspace with guarantees of stability.

delta_p_delta_x 2 hours ago | parent | prev | next [-]

On Windows, the stability guarantees are opposite to that of Linux. The kernel ABI is not guaranteed to be stable, whereas the Win32 ABI is.

And frankly, the Windows way is better. On Linux, the 'ABI' for nearly all user-mode programs is not the kernel's ABI but rather glibc's (plus the variety of third-party libraries, because Win32 has a massive surface area and is an all-in-one API). Now, glibc's ABI constantly changes, so linking against a newer glibc (almost certainly the 'host' glibc, because it is almost impossible to supply a different 'target' glibc without Docker) will result in a program that doesn't run on older glibc. So much for Torvalds' 'don't break userspace'.

Not so for a program compiled for 'newer' Win32; all that matters are API compatibilities. If one only uses old-hat interfaces that are documented to be present on Windows 2000, one can write and compile one's code on Windows 11, and the executable will run on the former with no issues. And vice versa, actually.

samus an hour ago | parent | next [-]

The Win32 ABI is also just a wrapper on the native API, which is only stable in practice, but not officially according to any Microsoft documentation.

Glibc is userspace seen from the perspective of the Linux kernel.

delta_p_delta_x 16 minutes ago | parent [-]

It doesn't really matter if it's 'just a wrapper', because said wrapper provides an ABI. Even if the underlying Native API changes, the interface the wrapper presents to other compiled binaries won't. The latter will contain caller/callee register setup, type layouts, function arguments and more for that wrapper.

Cygwin is also 'just a wrapper' for the Native API and Win32, and look how drastically it changes the ABI of applications.

monocasa 2 hours ago | parent | prev [-]

A lot of the native API is considered stable these days. The actual signals aren't, but the wrappers in ntdll are.

usrnm 2 hours ago | parent | prev [-]

> I don't see why I would want to use libc

To make your code portable? Linux-only software is even worse than Windows-only

koakuma-chan an hour ago | parent [-]

Let me narrow down the scope here. I am a Rust developer, developing software that will run on my Linux server. Why would I want to use libc? Why does Rust standard library use libc? Zig, for example, doesn't.