In order to better understand the concepts of WinRT, C#.NET, C++, etc. in the new Windows 8 environment, let us write some code. Then we will explore what happens under the hood when we compile code and run the applications. This will be explained in many parts as we progress.
First let us understand what WinRT is and what makes a WinRT DLL or WinRT component. There is no better place to start other than creating a WinRT component ourselves and examining it. So lets get started.
Creating a WinRT Component DLL:
Open VS 2011 Developer preview. Click on New Project. In the New Project Dialog, from Installed section, select Visual C++ in the left hand side navigation tree. Select WinRT Component DLL from the project templates and name the component as CppWinRTComponentDll. Click OK as shown in Fig 1.
Fig 1: Selecting Visual C++ template for WinRT Component DLL project.
Note: As a test, I tried to create a component with name C++WinRTComponentDll and VS 2011 C++ compiler shows many errors in the class files created by the wizard. So try to avoid ++ in the names.
Glimpse of new Visual Studio 2011 Developer preview edition:
In the new Solution Explorer, hover over the files and for each file you will find that there is an icon on the far right edge; View additional information (Ctrl+Right) icon.
When you select an item in Solution Explorer, whether it be a file or class or method, etc., the icon appears on the right edge of the selection. The tooltip says "View additional information (Ctrl+Right)". Clicking on the icon will invoke the "View Additional Information" menu which, for class files and members will provide relationships that you can view in Solution Explorer. Examples include "Base/Derived Types", "Find References", "Call Hierarchy", Calls, Is Called By, Is Used By etc. as shown in the following Fig 2.
Fig 2: Figure showing the View additional information (Ctrl+Right)icon.
Goto WinRTComponent.cpp file and delete the WinRTComponent definitions. Goto WinRTComponent.h and delete some of the default code. The code of the .h & .cpp files will look as shown in the following code snippets.
We need the namespace CppWinRTComponentDll. Everything in WinRT has to be part of a namespace because the resolution of the DLL is based on a namespace that the class is in and that’s how other programming languages will find the class based on namespaces and DLL name.
Let us declare a sealed class called CalculatorSample in WinRTComponent.h as shown in the following code snippet. The class is sealed as we don’t want others to derive from it. Sealed means no Inheritance.
Why use Ref in front of the class:
Previously some of us worked on COM and created COM components. For that we have to create an interface, we have to specify that we are deriving from IUnknown (or derived) , put this in an MIDL file, use the MIDL Compiler to generate files, then go to C++ component, implement this interface, then create a class factory for it to create an instance and register this component. and the list goes on.. Well, all of this is done by using the keyword Ref in front of the class. So here we are creating WinRT Component that is accessible by dynamic languages as well. Here we are saying that CalculatorSample is a ref class, a class for WinRT. In other words, a ref class is a user-defined class that can be passed across the ABI boundary.
In the WinRTComponent.cpp, define the CalculatorSample class member functions as shown in the following code snippet.
To sum it up, the WinRTComponent.h file should have the following code.
WinRTComponent.cpp file contains the following code.
Do not Compile the project. pch.h and pch.cpp are like stdafx.h and stdafx.cpp in VC++ MFC.
This completes the creation of a WinRT Component DLL.
Let us create a new application and try to access the WinRT Component DLL that we just created. For that, I will use C#.NET, so that we can know how to call a WinRT Component DLL from C#.NET application.
Right Click on the Solution CppWinRTComponentDll, Click on Add and select the New Project menu item as shown in Fig 3.
Fig 3: Adding a New project to the CppWinRTComponentDll solution.
Select Visual C# –> Application template and name the project as CSharpApplication as shown in Fig 4.
Fig 4: Creating a Visual C# Application project in VS 2011 Developer Preview.
Add a reference to the WinRT C++ calculator class we created to the C#.NET application as shown in the following figures.
Fig 5: Right click on References folder and Select Add Reference…
Fig 6: Select Solution tab in the left hand side navigation panel and select Projects. You should be able to see the CppWinRTComponentDll that we just created. Select CppWinRTComponentDll and click on Add button. click Close and go to step 6 if you have not encountered any error.
If you have compiled the C++ DLL by mistake before adding the reference, you will get a Failed to add reference dialog as shown below.
Fig 7: Failed to add reference dialog.
To fix the Failed to add reference dialog issue, clean up the CppWinRTComponentDll project as shown in the following figure 8.
Fig 8: Right Click on CppWinRTComponentDll project, select Project Only, then select Clean Only CppWinRTComponentDll
Now repeat step 5 again to add a reference to the CppWinRTComponentDll and you should see the green circle icon with tick inside it as shown in Fig 9. This means the component is successfully referenced in the project.
Fig 9: Component successfully referenced in the project.
Open MainPage.xaml file and add three text boxes to show the result of addition, subtraction and multiplication values returned from the C++ WinRT Component DLL.
Add the following XAML code.
Open MainPage.xaml.cs file and add the following code.
To use the C++ WinRT Component DLL that we just created we need to specify it in the C#.NET project by mentioning using CppWinRTComponentDll;
In the MainPage(), add the following code.
The complete MainPage.xaml file XAML code is
The complete MainPage.xaml.cs file C#.NET code is
Step 8: Build the solution.
The following information will be displayed in the output window. See the highlighted information. The Visual Studio 2011 is compiling the projects as well as deploying the projects. Later, we will see in detail what happens during deployment and how the applications is run by Windows 8.
1>—— Build started: Project: CSharpApplication, Configuration: Debug Any CPU ——
1> CSharpApplication -> C:\Users\Prathima\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\CSharpApplication\bin\Debug\csharpapplication.exe
1> CSharpApplication -> C:\Users\Prathima\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\CSharpApplication\bin\Debug\CSharpApplication.build.appxrecipe
2>—— Deploy started: Project: CSharpApplication, Configuration: Debug Any CPU ——
========== Build: 1 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========
========== Deploy: 1 succeeded, 0 failed, 0 skipped ==========
The output of the programs is the application
Download the source code from here.
"The future belongs to those who see possibilities before they become obvious." – John Scully
Note: This code is developed using Windows 8 & Visual Studio 2011 developer preview, which might change when the actual versions are released.