back to article The API that will not die: Microsoft opens crypt to unleash Win32 on Rust

The Win32 API is being opened up to more languages by Microsoft via the win32metadata project. The Windows API exposes large chunks of the Windows operating system to programmers. If you code in C or C++, the API calls are "readily accessible," according to Microsoft. Anything else usually requires some sort of wrapper. An …

  1. karlkarl Silver badge

    This looks to be a similar approach that Gtk has traditionally used.

    It is so annoying that so much effort is on binding all these other languages to C. I honestly think that just embedding a tiny C compiler in other languages just to consumer header files and help link against native objects could be a better solution than others. For example I imagine C++ would not be nearly as popular if it wasn't one of the few languages which can natively consume C.

    Looking at the trendy stuff, most of Rust's crates.io is filled simply with bindings to C libraries. They should just bolt on a tiny C compiler and be done with it. I think the only language that is going in the generally correct direction is Go where they do allow some C in the go preamble. However they are still very far from utilizing C headers.

    C at this point shouldn't be thought of as a language but pretty much base platform. Better integration with it can only improve other languages.

    1. Chewi

      FFI

      I think this is basically what FFI gives you for many languages but this approach is never as nice as proper hand-crafted bindings.

      1. karlkarl Silver badge

        Re: FFI

        The FFI allows you to call C libraries, in a similar way to JNI. These are what allows bindings to be created but unfortunately do not replace bindings. Unfortunately it is still a lot of work. Some of it can be automated to an extent but C libraries are often far more intricate than that. Simple things like callbacks or "who holds the data" cannot be easily automated.

        1. Daniel von Asmuth

          Re: FFI

          Java probably had the right idea: a modestly complex core language plus a rich set of libraries, which provide a modicum of platform neutrality and portability. Code written against the Windows API does not run reliably on IBM Z or MacIntosh.

          That leaves developers with an occasional need for using some Open Source libraries for functionality that no Operating System provides itself.

    2. Loyal Commenter Silver badge

      I'm not sure it's that simple.

      A lot of languages don't support the same types as C. In the most extreme cases, they may have no variable typing at all. If your C library expects an unsigned short, then how do you manage this natively with a language that only has the concept of a "number" type?

      Add to that the fact that many languages also do not have pointers, they only have types that are either value or reference types (C# is a good example of this, if you ignore the shenanigans you can get up to inside 'unsafe' blocks). How would you pass a char* to a function that expects one, when your language only has immutable strings to work with? Or a block of allocated memory?

      Things like function pointers are also likely to cause a headache.

      By turning every language into something that contains a C compiler, you would in essence be making them all into something that is an extension of C. Some languages are going to be more amenable to that than others (AFAIK, you can, for example, make C# accept pretty much any C code if you tell it that your code is unsafe, but you have to jump through some hoops to make it play nicely with the concept of "managed code"). Some are going to require wholesale redesigning to make them compatible.

      1. DrXym Silver badge

        Most languages would figure a way to fudge support. e.g. if I wanted to call Win32 from NodeJS I'd probably have a nice Win32-esque module that took Win32 esque objects but under the covers it would make heavy use of byte buffers, marshalling the bytes in and out of JS structs and call some kind of C native DLLinvoke. It wouldn't be super efficient but honestly if I'm writing code in JS then that's not an issue I probably care about a huge amount.

        1. Loyal Commenter Silver badge

          Of course, most languages *could* do so, but by adding in a C compiler to them all, you are adding in extra complexity for a niche use case, and when you start doing things like that, you should stop and ask yourself "why"? You are both constraining the language you are altering and forcing it to have concerns about "C" type things that the language designers may have very consciously designed out, like pointer arithmetic and memory management. Plus, you are essentially forking the C compiler each time, and having lots of separately maintained forks of the same thing NEVER ends well.

          As a rule of thumb, you should only add to something that which you need; it reduces the maintenance cost, and makes the result measurable and testable.

          If you have discrete interfaces for the functionality you want to export from one language to another, then you can worry about the maintenance of that code in its native language (in this case C) and only have to concern yourself with consuming the interface in the host language. Traditionally, this was through entry points in DLLs, which would have a clearly defined interface. If your target language didn't support the required types (for example, if the DLL advertises an entry point with a signature that requires an unsigned short, but your language only has 32 bit signed integers), then you would build a shim to handle that.

          I would expect that these OS system calls work in much the same way, except you just specify the namespace they live in, and the language now knows about them without you having to declare the entry points explicitly, and handles all the nastiness like memory management, and building structs with various char*s or whatever in them, where it is needed.

          The key here is separation of concerns - In this case, you don't really want to be having to build various libraries every time you use them, that is the concern of the person who supplied them in the first place. You only want to be concerned with your code that consumes them, so why would you need that C compiler to build them anyway?

          1. karlkarl Silver badge

            Yeah, I do see what you are saying. Particularly your last point of using a compiled binding so you don't need the C compiler to compile it you can just consume it (though in my experience, being able to compile the binding myself greatly improves maintenance in case the upstream "gets bored" of the project.

            However your mention of it being a niche use-case I don't entirely agree with, the requirement of a binding is certainly not nice; if you look at i.e a typical Python project you will see that the sheer size of binding code often outweighs the actual program!

            If some of the other issues you mentioned could be addressed, the C "extension" isn't really to aid making a binding, it would avoid it entirely. Just like C++ can usually avoid bindings by using C directly*.

            * Yes, this isn't always ideal, often a C++ binding is still desirable to leverage RAII and OOP-style objects.

  2. DrXym Silver badge

    Bindings already existed

    Rust has had Win32 / WinRT bindings via the winapi crate for a long time but they're manually defined. The potential benefit of the new approach is that they are machine generated and need less maintenance to benefit Rust or any other language target. It might even be possible to generate the bindings as part of the build process, i.e. the external crate just contains the meta data and a build.rs and bindings get generated automatically depending on what the code is using. It could also generate documentation and other stuff onto the bindings so they are available in the IDE.

  3. Anonymous Coward
    Anonymous Coward

    Promising

    Took a look at the project, and it looks like it has every opportunity to be extremely useful.

    Sorry to be pessimistic though, but since this is New Microsoft, $100 says:

    1) Impressive and productive burst of activity until project is half finished; then

    2) Work slows and eventually grinds to a halt; and then

    3) Project is effectively abandoned before it's complete / reliable enough to be used in major development.

    1. NetBlackOps Bronze badge

      Re: Promising

      My lawn is littered with abandoned MS tech, as I was just brought up yesterday on Twitter about another piece of MS tech. Here's hoping it will achieve something.

  4. anothercynic Silver badge

    Python ;-)

    We used to have *lots* of fun with Python calling into Win32 APIs at a job I used to have. Included things like hacking into the registry to remove software that wouldn't uninstall without a UI (ahhh, how funny that is given I've harped on about UIs elsewhere today)... This can only get better!

    1. Anonymous Coward
      Anonymous Coward

      Re: Python ;-)

      Did similar things with ActiveState's version of Perl back in the 1990s. If I recall correctly that was how ActiveState started, offering a version of Perl that was distributed as binaries for Windows with extensions to support Win32 APIs. Then they branched out into supporting other scripting languages like Tcl.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Biting the hand that feeds IT © 1998–2021