A .NET Dev’s baby steps trying to share native code between Win8 and WP8

This is a walkthrough of what i had to do to setup native code sharing between Windows 8 and Windows Phone 8 (using the leaked WP8 SDK). My knowledge of the native world is quite limited and there might be other better ways of doing it. Feel free to comment if you know more about the subject and help out this poor .NET dev ūüôā

First we create our Native C++ WinRT Component :

Add New Windows Runtime Component Project

Then we create our Native C++ Phone Runtime Component :

Next we delete from both projects the autogenerated files. From the WinRT project delete the files named Class1.cpp and Class1.h and from the PhoneRT project delete the files named NativeSharedPhoneRT.cpp and NativeSharedPhoneRT.h.

What we need next is a simple class that we will want to share between the two projects. Lets call it MySharedClass. We will create it only on the WinRT side and we will link to it from the PhoneRT side.

I am expecting that i can use preprocessor flags in the same manner that we used to do between Silvelight/WPF and Windows Phone. So the next question is “how do i define my preprocessor directives in C++ projects”?
These simple steps worked for me :

  1. Open the properties of the NativeSharedWinRT project and go to “Configuration Properties -> C/C++ -> Command Line
  2. Enter “/D “_WinRT”” (without the outside quotes) in ¬†“Additional Options” and click Apply.

Screenshot below :

(Note: the only reason i named the directive with an underscore is because the debug directive in one of the templates was named _DEBUG.Thought it might be a convention or something)
As¬†jalfdjalf¬†pointed out directives starting with underscores are reserved (makes sense) so its OK to name our own as we¬†wish (i.e PhoneRT, WinRT).Btw i used PhoneRT instead of the more “official” WinPRT for the phone because its¬†a lot more¬†distinguishable¬†from WinRT.

Do the same thing for the NativeSharedPhoneRT project but add this “/D “_PhoneRT”” ¬†instead in the Additonal Options.
Great. Now we have setup our preprocessor directives for both our shared projects. Time to create the shared class. Go to the NativeSharedWinRT project and add an empty MySharedClass.cpp file and an empty MySharedClass.h file. Then go to the NativeSharedPhoneRT project, click “Add existing item” and navigate inside the NativeSharedWinRT folder to locate the newly created files and select those. These files are now linked and the project structure should look like this :

(Note: I tried linking the pch.cpp and pch.h files as well but VS and the compiler didnt like that for
some reason so i kept them unlinked in order to move one)

Ok so far. Now lets add code to our shared class and see how we can start sharing.
Below is only a screenshot of what the code inside our files should be but you will be able to
download the source code and copy paste directly (see download link at end of post).

Notice how opening the header file from inside the WinRT project that the _WinRT directive is active but not the _PhoneRT one just as we wanted. SharedMethodAsync is a WinRT-Style asynchronous method exposed to both WinRT and PhoneRT.

I had planned to also show off how projections worked in the WinRT world but i couldn’t get it to work easily.The plan was to expose a WinRT type like IMap or IIterable and see how they¬†show up projected in C#.

Here is our .cpp file (opened from inside the NativeSharedPhoneRT project) :

Now its time to create our C# clients (one for WinRT and one for PhoneRT) that will consume our shared native libraries.
First is the WinRT C# Client :

Once created click “Add Reference” on it and select the NativeSharedWinRT project.

Big pause here! Can you say “where’s my P/Invoke dude?” ¬†ūüôā
Now that’s what i call¬†seamless.
Small note.Never forget that the interop cost is ALWAYS there when going back and forth from native <-> managed.Keep in mind that usually there is an interop cost when going native <-> managed and
that applies to WinRT as well although Microsoft has done a lot of work to minimize it.

Then is our PhoneRT C# Client :

Once created click “Add Reference” on it and select the NativeSharedPhoneRT project.

This is how the project structure should look now :

Finally lets see what the code looks like from both client projects.
This is what we get from the Phone Client :

and here is what we get from the Win8 Client :

And that’s it! That was certainly fun ūüôā

Source code for this post is here