Available on GitHub

Modern is now available for download from GitHub. This is the first public preview of the Modern project and I look forward to your feedback!

Here it is: https://github.com/kennykerr/modern

Credits

I would like to thank the developers who tested private builds or contributed in one way or another including James Clarke, Ales Holecek, James McNellis, Jeremiah Morrill, Larry Osterman, Raffaele Rialdi, John Sheehan, Kirk Shoop, and Charles Torre. Your feedback helped to shape my understanding of the Windows Runtime and the modern C++ language projection.

What is Modern?

Modern is a Standard C++ language projection for the Windows Runtime. The Modern compiler produces a header-only library designed to provide Standard C++ developers with first-class access to the Windows API. As I’ve previously shown, Modern provides a classy type system to target the Windows platform with standard C++.

Need a simple example? The Windows.Foundation namespace provides the Uri class with its constructor accepting a string argument. The C++ developer can call this in the most natural way:

using namespace Windows::Foundation;

Uri first(L"http://kennykerr.ca/");

The Uri class also provides the CombineUri method, which returns another Uri object:

Uri combined = first.CombineUri(L"articles");

And it provides a way to get the canonical representation as a string:

String string = combined.ToString();

That’s all there is to it. No pointers or hats, no reference counting or error codes, nothing that isn’t straightforward and natural to the casual C++ developer.

But I need more power!

Sure thing. Modern provides a library-based language projection. That means you can drill down as far as you want to go. Creating a Windows Runtime class involves the use of an activation factory.

auto factory = GetActivationFactory<Uri, IUriRuntimeClassFactory>();

If you’ve ever tried calling the operating system’s RoGetActivationFactory function you’ll know what a saving this is. With the factory in hand, I can call the logical construction method to create the Uri object:

Uri uri = factory.CreateUri(L"http://kennykerr.ca/");

Not satisfied with the Uri class? You can just ask for Uri’s default interface:

IUriRuntimeClass default = uri;

But if you do that, you’ll notice that IUriRuntimeClass doesn’t provide the ToString method. This comes courtesy of the IStringable interface also provided by the Uri class. No problem, we can just query for it:

IStringable stringable = default.As<IStringable>();	
String string = stringable.ToString();

The Windows Runtime is built on the essentials of COM. That means IUnknown** and lots of HRESULTs, right? Wrong. Modern takes advantage of C++11 and beyond to provide a truly modern language projection for the Windows Runtime. So while it is still COM under the hood, a C++ developer should think in terms of references rather than pointers. Practically nothing is off limits to the developer hungry for power, but you don’t need to sacrifice productivity or safety along the way. About the only thing that Modern prohibits is explicit reference counting. It uses C++11’s move semantics to handle reference counting reliably and sparingly. So, given an IUnknown reference:

IUnknown unknown = uri;

I can call the modern equivalent of IUnknown’s QueryInterface:

IUriRuntimeClass uri = unknown.As<IUriRuntimeClass>();	

But there’s no AddRef or Release methods. You can even retrieve the underlying interface pointer and call QueryInterface directly:

IUriRuntimeClass uri;
HRESULT hr = unknown->QueryInterface(set(uri));

But even here the reference counting is hidden away. The uri object receiving the new reference takes care of its own reference counting and the AddRef and Release virtual functions are still inaccessible. So while all of the underlying ABI virtual functions are just a -> away, the reference counting is safely and efficiently taken care of by the library and the compiler.

What if you still desperately need to shoot yourself in the foot? No problem, just get the naked COM interface pointer:

ABI::Windows::Foundation::IUriRuntimeClass * danger = get(uri);
danger->AddRef();

The rabbit hole goes deeper still but I’ll leave it there for the moment.

What’s ready?

The GitHub repository includes library sets for developing apps for Windows 8.1 and Windows 10. It includes full projections containing everything you might need to build anything you can imagine, but it also contains smaller library sets for scenarios where you might not need XAML or just want to use the Windows Runtime from a desktop app, console, or service.

You can use this public preview to build XAML apps or apps directly with CoreWindow. You can write console and desktop apps that just happen to use Windows Runtime components but don’t rely on an app container or core dispatcher. It’s up to you.

What’s next?

I am not releasing the Modern compiler at this time. The compiler is required for component development, to produce updated library sets, as well as project templates.

Support for binary composition, required by XAML, is currently experimental. This is likely where I’ll be spending a lot more time improving the language projection. You can however write a simple XAML app and take advantage of the existing support for binary composition. An example is provided on GitHub.

XAML also requires a limited form of reflection. This is mostly working but it needs a bit more time to mature and I need to figure out how XAML designer support can be integrated.

Support for creating collections is in the process of being rewritten and I’ll be including that in an upcoming drop. You can of course consume collections produced by the Windows API, but you cannot create your own collections very easily. Expect this in the next update.

Windows Runtime structures are currently projected quite sparsely. In particular, better support for Numerics is coming.

Clang support is experimental. The current Clang build for Windows doesn’t work too well with the RTM build of Visual Studio 2015. Debugging is not integrated and there is a mismatch between the Clang and CL compiler options.

Visual Studio and the IntelliSense engine still struggles a bit with the large headers and a lot of the metaprogramming, but the compiler is satisfied and that’s what counts. This is the reason why the Modern library is spread out across a number of headers rather than just shipping in a single header file. I’ve done a lot of work to simplify the code. Earlier builds of the language projection took a few minutes to precompile. The code was beautiful with elegant templates but compile time was a killer. I’m actively working on reducing precompile time, but it is already quite reasonable.

Finally, I was hoping to secure some kind of corporate sponsorship for the Modern project but that has not materialized. This means that I’ll be updating Modern as I have free time to commit to the project.

Enjoy!

40 thoughts on “Available on GitHub

  1. Sai Jagannath.

    Congrats Kenny for this awesome library. If I want to create a XAML app, what project type I should choose in Visual Studio ? The sample in the github page you have has a Blank App type of template chosen ?

    Reply
    1. Kenny Kerr Post author

      None of the Visual Studio templates support creating XAML apps with standard C++. I would just start with the sample XAML app on GitHub that’s preconfigured and go from there.

      Reply
    1. Kenny Kerr Post author

      The sample illustrates how to create an app based on Windows::UI::Xaml. The XAML designer support (with actual markup) requires Visual Studio IDE integration that I haven’t yet figured out.

      Reply
      1. superlloyd

        OIC!
        Well, if you haven’t figured it out yet, I am unlikely to resolve it by myself! ^^
        I shall await your further progress! Good luck!
        And thanks for that great library! 🙂

  2. A.J.

    This is awesome! So super cool! I can do so much with this.

    If you are willing (perhaps in an upcoming post) I wasn’t able to figure out how to use the OCR with it. Here is what I had when I got stuck:

    “`
    void Test()
    {
    Modern::Windows::Storage::StorageFile::GetFileFromPathAsync(L”c:\\test.png”)
    .Completed([](auto const & sender, AsyncStatus)
    {
    auto file = sender.GetResults();

    file.OpenAsync(Modern::Windows::Storage::FileAccessMode::Read)
    .Completed([](auto const & sender, AsyncStatus)
    {
    Modern::Windows::Storage::Streams::IRandomAccessStream stream
    = sender.GetResults();

    Modern::Windows::Graphics::Imaging::BitmapDecoder::CreateAsync(stream)
    .Completed([](auto const & sender, AsyncStatus)
    {
    Modern::Windows::Graphics::Imaging::BitmapDecoder decoder
    = sender.GetResults();

    decoder.GetSoftwareBitmapAsync()
    .Completed([](auto const & sender, AsyncStatus)
    {
    Modern::Windows::Graphics::Imaging::SoftwareBitmap bmp
    = sender.GetResults();

    Modern::Windows::Media::Ocr::OcrEngine ocrEngine
    = Modern::Windows::Media::Ocr::OcrEngine::TryCreateFromUserProfileLanguages();

    ocrEngine.RecognizeAsync(bmp)
    .Completed([](auto const & sender, AsyncStatus)
    {

    });

    });
    });
    });
    });
    }
    “`

    I got the “REGDB_E_IIDNOTREG Interface not registered” when calling RecognizeAsync.

    Anyway very thankful that you worked on this! Please keep it up if you can!

    Reply
  3. romka2411

    Idea of light-weight and clean c++ app so cool! When I saw it I was really excited!
    Just trying port my code into CoreApp sample. And – there`s troubles. First of all I cant use Picker (when trying set ViewMode – error c2228)

    Reply
      1. romka2411

        just leaved report.
        The idea is so great! Launch time, using memory and just 2 failed tests in “Windows app certification kit” (may be my fault). Cant wait next release with concurrency to begin porting code I have

  4. Karim Jordan

    Sir, this is more than awesome and exactly what C++ developers need to target the Windows Runtime. I am really looking forward to the development of the Modern C++ projection and I hope that you keep working on it. Everyone else is invited to take a look at the following link and share it with other developers on social networks. Let’s support Kenny Kerr and give him our votes! https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/9549084-add-official-support-for-the-modern-c-projection

    Reply
      1. romka2411

        the only part I use from PPL is create_task(…).get() which is close to just type await. As for me now I`m making linear code from WinRT file IO where a lot of resumable functions, so I need just wait() and get(). Or I`d like to see some example of resumable functions and provided “await”

      2. Alexander Riccio

        Ugggh, there are **so many** “using namespace”s in that example. I have trouble reading code like that – it’s part of my aversion to C++/CX, where there are even more of those!

      3. Kenny Kerr Post author

        In this case these are standard C++ namespaces. You are free to be more verbose and use the fully-qualified names everywhere, but namespace in general are a reality of contemporary APIs.

      4. romka2411

        (There was no reply under last message)
        Got it. Sorry for noob questions. Sad this only for x64. So if there the only allowed method to stop thread until “Async” function completes is PPL, i`ll wait for adapters

      5. Karim Jordan

        Does this also work with ARM or are there any parts of Modern that do not work with ARM? Also on your DirectX page you say the future of dx.h is Modern, what do you mean?

      6. Kenny Kerr Post author

        Modern is just standard C++ and can target whatever platforms Visual C++ itself can target.

        Regarding DirectX, the Modern compiler can also produce a library for the DirectX family of APIs since they are also COM-based. I have not yet released those projections.

      7. Karim Jordan

        Great! Can’t wait for the XAMl Designer integration and DX support! In the meantime I will sign up on Pluralsight and start watching all your videos.

  5. romka2411

    Is there any forum related to this library? I`d like to ask some questions about writing code under this library, suppose neither this site or GitHub issues are for this stuff

    Reply
  6. Andy

    It’s possible using your Modern compiller for generation wrappers from other COM library besides WinRT? (It would be nice for refactor my app for windows 7).

    Reply
  7. Shane

    Kenny: I 3 voted the Dev feedback that was started to support you, hopefully that’s likely to happen soon, I’d love to see the modern.exe compiler & what sort of progress your making with the point’s you discussed earlier (XAML and so forth). I was a heavy C++/CLI dev and am thrilled to see the work you’ve done, I haven’t really taken to C++/CX even though the similarities are substantial to CLI. Would much prefer to get the sorts of advantages you’ve brought with the first beta to wider set’s of code 😉 Thanks again!

    Reply
  8. Johann Kollmann

    Hello Kenny,

    My name is Hans Kollmann, you make a perfect work fro native developer’s. I an now for one Man excellent!!!

    Best regards Hans Kollmann from Austria.

    Reply
  9. me

    Great work, Kenny, and congratulations on getting into Microsoft. I can’t wait to see your good works become officially supported and emerge in Visual Studio. I hope that happens very soon!

    On a side note from looking at the “Credits” section — it’s nice to know the names of the ONLY TEN people on Earth (now including you) who truly understand how all this stuff actually works.

    Reply
  10. Arno Schoedl

    In your COM smart pointer, I believe your self-assignment checks are ineffective. The problem is that equality of pointer values is not sufficient to ensure that two COM pointers are not pointing to the same object. The only way to reliably compare COM pointers is through the identifying IUnknown, and you must do a QueryInterface to get one. In my COM smart pointer, I simply do AddRef first and Release then to avoid the problem.

    Reply
    1. Kenny Kerr Post author

      The ComPtr class is not concerned with COM identity. It merely checks whether the same pointer value is being assigned to itself. A different pointer to the same COM object (e.g. different interface) is considered a different ComPtr. That being said, I can’t wait to share what I’ve been working on with all of you. There’s been a lot of good progress in many areas.

      Reply
      1. Karim Jordan

        I can’t wait! Hope to see something before BUILD 2017 🙂 I still have to complete your Pluralsight courses on COM and the Windows Runtime though. Good job!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s