14

Microsoft (chiefly, Herb Sutter) recommends when using WinRT with C++/CX to keep WinRT at the boundaries of the application and keep the core of the application written in standard ISO C++.

I've been writing an application which I would like to leave portable, so my core functionality was written in standard C++, and I am now attempting to write a Metro-style front end for it using C++/CX. I've had a bit of a problem with this approach, however. For example, if I want to push a vector of user-defined C++ types to a XAML ListView control, I have to wrap my user-defined type in a WinRT ref/value type for it to be stored in a Vector^. With this approach, I'm inevitably left with wrapping a large portion of my C++ classes with WinRT classes.

This is the first time I've tried to write a portable native application in C++. Is it really practical to keep WinRT along the boundaries like this? How else could this type of portable core with a platform-specific boundary be handled?

Bret Kuhns
  • 242
  • 1
  • 8
  • Something like MVVM, where Model is standard C++, V and VM are WinRT interop objects? – Max Aug 07 '12 at 17:09
  • I thought of that, but each VM effectively turns into a WinRT wrapper around my standard C++ models. Plus all the ViewModel code becomes specific to WinRT. – Bret Kuhns Aug 07 '12 at 17:13
  • I thought VM's were supposed to be specific for the View tech stack? Of course, if you can avoid it it's obviously better not to have to wrap everything! – Max Aug 07 '12 at 17:27
  • Good point. It seems the only reasonable way to get my models' data to and from the view would be with a ViewModel layer for each platform. – Bret Kuhns Aug 07 '12 at 17:44
  • 5
    *"but each VM effectively turns into a wrapper around my standard models."* - that's pretty common for view models in any scenario. – MattDavey Aug 07 '12 at 18:19
  • It's kinda like what you do when you enter the closet every morning.. you dress yourself according to what the whether/environment is like outside and your plans on any given day. It seems a lot easier than maintaining a bunch of pre-dressed clones of yourself and sending the proper one out on a given day... – David Cowden Aug 10 '12 at 17:45
  • @BretKuhns - have you uncovered any additional information on this question? I'm curious to know if there's an answer to this or not. It's a similar question if you want to use Silverlight since you can't add a non-silverlight project reference to a silverlight project. –  Sep 07 '12 at 14:51
  • 1
    @GlenH7, I believe comments have mostly answered this for me. I had reached the same conclusion, but was hoping someone had a more clever idea in mind. In general, things are just the way they are. You can do your best to isolate portions of your code, but for the most part you will end up needing to rewrite platform-specific portions of the code (such as in the ViewModel examples above). – Bret Kuhns Sep 07 '12 at 15:41
  • 1
    @GlenH7 Perhaps the only way to keep your application code consistent across platforms is to write your own platform abstraction layer, but those layers will end up being what I was trying to avoid in the first place. It's simply moving the problem around with a layer abstraction to isolate things. Perhaps helps, but in the end you're still doing the work. – Bret Kuhns Sep 07 '12 at 15:43
  • @BretKuhns - thanks for the update. It gives me an excuse to do some research on the matter. We're struggling with similar issues on our team courtesy of Silverlight, and it's not encouraging that we may have the same issues again with RT. –  Sep 07 '12 at 17:55
  • One more - have you tried the "add as link" trick, and / or does that work in WinRT? In our case, we can create a silverlight project, then Add Existing Item, and then use the Add as Link option from the Add dropdown. We're using VS2010 if that matters. –  Sep 07 '12 at 18:02
  • Maybe your core part is not heavy enough to make it worth the hassle? When people need most to care about split between the standard C++ and the boundaries in C++/CX, or Objective C, or Java, is when a huge mature product of hundreds of thousand lines of standard C++ must be ported. In such case it is very important that they can avoid a complete rewrite, but use glueing techniques to connect the two worlds. – Alex Cohn Oct 09 '12 at 12:38
  • @alexcohn Right, and that makes perfect sense. I asked the question with my fingers crossed that there was some silver bullet I was missing to reduce the glue code between standard C++ and C++/CX. I haven't seen any better way, so I've since taken it for what it is. Can't blame me for hoping to reduce the amount of glue ;-) – Bret Kuhns Oct 09 '12 at 15:10
  • 1
    We tried once to create a "silver bullet" to seamlessly glue a C library to Java on Android. Finally it could work, after spending ~×10 more time and using exotic debugging techniques (to work around the abnormal behaviour on the frontier). Definitely, it was fun. – Alex Cohn Oct 09 '12 at 17:18
  • Another didactic example of a similar task: http://msdn.microsoft.com/en-us/magazine/jj658972.aspx – Alex Cohn Oct 09 '12 at 18:32
  • @alexcohn That sounds more like a bronze bullet to me... thanks for the article! – Bret Kuhns Oct 10 '12 at 01:14

2 Answers2

8

IMHO (old programmer; work at Microsoft but this is a personal opinion): before I can answer this question, you have to anwser this other question:

Where is the code moving to? If you're sticking with a single platform (in this case, WinRT), then be close to the platform -- and that means using the existing abstractions. Per your example, your code would then use Vector^ in order to match the WinRT needs.

OTOH, if you're moving somewhere else (VMS rocks!), then standards based makes sense.

Given that the three biggest portable, tablet-like platforms in the marketplace all use different languages for common programming tasks, moving the code might not be a valuable option.

PESMITH_MSFT
  • 286
  • 2
  • 4
  • I agree. I started the project targeting WinRT, but knowing Android/iOS would be attractive platforms to port to, which prompted this question. I've since decided to write specifically against WinRT only. If the project itself draws a crowd, I'll worry about porting (or rather, rewriting to another platform) then. – Bret Kuhns Oct 14 '12 at 17:46
  • As @alexcohn pointed out, if the core functionality is heavy enough at the time that I decide to go cross platform, then it will be worth wrapping portable code with platform specific layers. Otherwise, I'll just rewrite the code and use test suites to verify behavior across different platforms (where appropriate). – Bret Kuhns Oct 14 '12 at 17:49
0

You don't have to use C++/CX, instead you can use the WRL (Windows Runtime Library) which is like the old ATL templates, not the 'pretend' C++ that is C++/CX. Its the "low level" approach from MS to consuming WinRT objects and is completely standard C++ like Grandad used to write!

It might not be as "nice" as C++/CX but that's a matter of opinion - my personal opinion is that C++/CX is the 3rd attempt at an extended C++, and is a 3rd failure. Ignore it and hope it goes the same way as the other 2 incarnations.

gbjbaanb
  • 48,354
  • 6
  • 102
  • 172