C++/CX Part 0 of [n]: An Introduction

C++/CX Part 0 of [n]: An Introduction

Rate This
  • Comments 65

Hello; I'm James McNellis, and I've recently joined the Visual C++ team as a libraries developer. My first encounter with the C++/CX language extensions was early last year, while implementing some code generation features for the Visual Studio 2012 XAML designer. I started off by hunting for some example code, and it suffices to say that I was a bit surprised with what I first saw. My initial reaction was along the lines of:

"What the heck are these hats doing in this C++ code?"

Actually, I was quite worried; because I thought it was C++/CLI—managed code. Not that managed code is bad, per se, but I'm a C++ programmer, and I had been promised native code.

Thankfully, my initial impression was uninformed and wrong: while C++/CX is syntactically similar to C++/CLI and thus looks almost the same in many ways, it is semantically quite different. C++/CX code is native code, no CLR required. Programming in C++/CLI can be very challenging, as one must deftly juggle two very different object models at the same time: the C++ object model with its deterministic object lifetimes, and the garbage-collected CLI object model. C++/CX is much simpler to work with, because the Windows Runtime, which is based on COM, maps very well to the C++ programming language.

Windows Runtime defines a relatively simple, low-level Application Binary Interface (ABI), and mandates that components define their types using a common metadata format. C++/CX is not strictly required to write a native Windows Runtime component: it is quite possible to write Windows Runtime components using C++ without using the C++/CX language extensions, and Visual C++ 2012 includes a library, the Windows Runtime C++ Template Library (WRL), to help make this easier. Many of the Windows Runtime components that ship as part of Windows (in the Windows namespace) are written using WRL. There's no magic in C++/CX: it just makes writing Windows Runtime components in C++ much, much simpler and helps to cut the amount of repetitive and verbose code that you would have to write when using a library-based solution like WRL.

The intent of this series of articles is to discuss the Windows Runtime ABI and to explain what really happens under the hood when you use the C++/CX language constructs, by demonstrating equivalent Windows Runtime components written in C++ both with and without C++/CX, and by showing how the C++ compiler actually transforms C++/CX code for compilation.

Recommended Resources

There are already quite a few great sources of information about C++/CX, and I certainly don't intend for a simple series of blog articles to replace them, so before we begin digging into C++/CX, I wanted to start with a roundup of those resources.

First, if you're interested in the rationale behind why the C++/CX language extension were developed and how the C++/CLI syntax ended up being selected for reuse, I'd recommend Jim Springfield's post on this blog from last year, "Inside the C++/CX Design". Also of note is episode 3 of GoingNative, in which Marian Luparu discusses C++/CX.

If you're new to C++/CX (or Windows Store app and Windows Runtime component development in general), and are looking for an introduction to building software with C++/CX, or if you're building something using C++/CX and are trying to figure out how to accomplish a particular task, I'd recommend the following resources as starting points:

  • Visual C++ Language Reference (C++/CX): The language reference includes a lot of useful information, including a C++/CX syntax reference with many short examples demonstrating its use. There's also a useful walkthrough of how to build a Windows Store app using C++/CX and XAML. If you're just starting out, this would be a great place to start.

  • C++ Metro style app samples: Most of the C++ sample applications and components make use of C++/CX and many demonstrate interoperation with XAML.

  • Component Extensions for Runtime Platforms: This used to be the documentation for C++/CLI, but it has since been updated to include documentation for C++/CX, with comparisons of what each syntactic feature does in each set of language extensions.

  • Hilo is an example application, written using C++, C++/CX, and XAML, and is a great resource from which to observe good coding practices—both for modern C++ and for mixing ordinary C++ code with C++/CX.

  • Building Metro style apps with C++ on MSDN Forums is a great place to ask questions if you are stuck.

Tools for Exploration

Often, the best way to learn about how the compiler handles code is to take a look at what the compiler outputs. For C++/CX, there are two outputs that are useful to look at: the metadata for the component, and the generated C++ transformation of the C++/CX code.

Metadata: As noted above, Windows Runtime requires each component to include metadata containing information about any public types defined by the component and any public or protected members of those types. This metadata is stored in a Windows Metadata (WinMD) file with a .winmd extension. When you build a Windows Runtime component using C++/CX, the WinMD file is generated by the C++ compiler; when you build a component using C++ (without C++/CX), the WinMD file is generated from IDL. WinMD files use the same metadata format as .NET assemblies.

If you want to know what types have been fabricated by the C++ compiler to support your C++/CX code, or how different C++/CX language constructs appear in metadata, it is useful to start by inspecting the generated WinMD file. Because WinMD files use the .NET metadata format, you can use the ildasm tool from the .NET Framework SDK to view the contents of a WinMD file. This tool doesn't do much interpretation of the data, so it can take some getting used to how it presents data, but it's very helpful nonetheless.

Generated Code: When compiling C++/CX code, the Visual C++ compiler transforms most C++/CX constructs into equivalent C++ code. If you're curious about what a particular snippet of C++/CX code really does, it's useful to take a look at this transformation.

There is a top-secret compiler option, /d1ZWtokens, which causes the compiler to print the generated C++ code that it generated from your C++/CX source. (Ok, this compiler option isn't really top secret: Deon Brewis mentioned it in his excellent //BUILD/ 2011 presentation, "Under the covers with C++ for Metro style apps." However, do note that this option is undocumented, and thus it is unsupported and its behavior may change at any time.)

The output is intended for diagnostic purposes only, so you won't be able to just copy and paste the output and expect it to be compilable as-is, but it's good enough to demonstrate how the compiler treats C++/CX code during compilation, and that makes this option invaluable. The output is quite verbose, so it is best to use this option with as small a source file as possible. The output includes any generated headers, including the implicitly included <vccorlib.h>. I find it's often best to use types and members with distinctive names so you can easily search for the parts that correspond to your code.

There are two other useful compiler options, also mentioned in Deon's presentation, which can be useful if you want to figure out how class hierarchies and virtual function tables (vtables) are laid out. The first is /d1reportAllClassLayout, which will cause the compiler to print out the class and vtable layouts for all classes and functions in the translation unit. The other is /d1reportSingleClassLayoutClyde which will cause the compiler to print out the class and vtable layouts for any class whose name contains "Clyde" (substitute "Clyde" for your own type name). These options are also undocumented and unsupported, and they too should only be used for diagnostic purposes.

Next Up...

In our next article (which will be the first "real" article), we'll introduce a simple C++/CX class and discuss how it maps to the Windows Runtime ABI.  The following is a list of all of the articles in this series that have been published so far:

  • @cppguy what do you mean their opinions differ? AFAIC before //build nobody including herb sutter let us know that C++ renaisance doesn't really mean C++ renaisance. Everyone including him, behaved as if C++ will be the language they've chosen. Everyone including herb sutter were talking how great C++ is, its advantages, etc, etc, how he loves C++, etc, etc. As it turned out, virtually nothing has been done with C++11 status. Moreover, herb sutter after //build tried to convince people that Cx is the way to go and that everyone should use it - this ended up with him being virtually told to go away and stop talking nonsense. Also, the poor alternative provided in the form of WRL only confirms the fact that C++ isn't first class citizen in MS and never was considered as such, despite the talks what were given before //build. What those facts tell about behaviour of herb sutter? Before //build: C++ is great, we love it, now it's C++ time etc etc.

    After //build: Cx is the best option, use it, it looks great, etc etc.

    All I'm saying is that such a behaviour can be seen as having traits of "sitting on a fence". This in turn (sitting on the fence) is very often one of main characteristics of traitors.

    They go where the best (whatever is best for them) is offered to them, and they have loyalty for nothing. In this case loyalty to C++ community.

    That's why I agree with the point of view of Knowing me, knowing you, a-ha.

  • @GregM Look, I have right to agree with someone's opinion even though this opinion may be hurtful to some other person. The point is that I believe and feel that Knowing me,....'s attitude and response however overheated it was nonetheless it was correct and justified response. How would you feel if for months someone tells you/promisses you that now is the time, now it's c++, now we are in full love with C++, now our IDE will be fully supporting c++ because this is the language of the future etc, etc,  ok? so for many months you hear those promisses and suddenly, one //build and not only you realize that nothing what has been told is in fact true but the person (herb sutter) who was telling all those stories, now suddenly, he changed the side of the fence and wants to convince you that in fact C++ isn't the best, that due to it's shortcomings they had to go with Cx, that Cx is the way to go, that this is better for everyone, etc, etc.

    How would you feel if someone treat you that way? What would you think about this person?

    That's why I repeat: I agree with Knowing me, knowing you, a-ha and I also believe that herb sutter by his behaviour before and after //build presented characteristics which can be only associated with traitors.

  • @atch666 You could very easily express that opinion without resorting to personal attacks like calling him a traitor.  Your points may be perfectly valid, but if you keep on with the personal attacks, you're just going to end up being ignored.  If that's what you want, fine, but that's not going to help you get your issue resolved.

  • @GregM and do you really believe that you will not be ignored by MS? Think about it Greg.

  • In any case, I'm not going to go around giving them more excuses to do it, plus there's really no justification for personal attacks.  If you can't see that, then there's obviously nothing more to say on that topic.

Page 5 of 5 (65 items) 12345