Building and using C++ WinRT components |
Written by Mike James | |||
Monday, 10 October 2011 | |||
Page 2 of 2
Using the component from VBTo use the component from VB .NET you have to go through the same steps. First you have to add a reference to the object select Add Reference, next click Browse and navigate to the Debug directory of the MyWinRTComp project and select the MyWinRTComp.winmd file. You also have to add a reference due to a glitch in the pre-beta software platform.winmd that you will find in C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\. You can also add Imports MyWinRTComp to the start of the program to avoid having to quote fully qualified names. Once this is done you can use the component as if it was a standard Basic object. First create an instance: Dim MyObject As New WinRTComponent Again this creates a COM object behind the scenes. You can use its properties, methods and events as if it was a standard VB object: MyObject.PropertyA = 1 Using the component from JavaScriptAll you have to do to make use of the component from JavaScript is, once again, load a reference. Right click on References in the Solution explorer and brows to the Debug directory of the MyWinRTComp project and select the MyWinRTComp.winmd file. After this the WinRT component looks just like a standard JavaScript object. However there are some slight differences from the way it all works in the other languages. The first is that there is no JavaScript equivalent of "using" or "import" - you have to use a fully qualified name. For example to create an instance of the object you have to use: var MyObject = The second difference is the JavaScript enforces a "camel case" style on method and properties. That is even if you have created a method with the name MethodOne it will be changed to methodOne i.e the first character is always lower case. With this difference taken into account everything works in the same way: var temp = MyObject.propertyA; Except at the moment it doesn't actually work. In the current build you get an error when you try to create the object. It does work if you add the WinRT component project to the solution and add the reference directly. Presumably this is a short lived bug that will be fixed in the next release.
Using the component in C++Interestingly using the component from C++ is probably the most difficult thing to do with the current state of the software - ignore the lack of Intellisense prompting and even some initial error messages. First to use the component you have to add a reference. Right click on the projects name and select References. When the dialog box appears select Add New Reference and navigate to the Debug directory of the MyWinRTComp project and select the MyWinRTComp.winmd file. You can also add using namespace MyWinRTComp; if you want to avoid typing fully qualified names. Once you have done this, there is no need to add a reference to platform.winmd in this case you can start to use the component. First we need to instantiate an object: WinRTComponent^ MyObject = Notice the use of ^ and ref new to create a reference and a new COM object. Once we have the reference to the COM object it can be used, with some slight modifications, as if it was a native object. For example: MyObject->PropertyA=1; The only slightly strange instruction is the use of the lambda to set the event handler. The Lambda is simply [](int i){}; which defines a dummy i.e. empty function with the signature (int) returning void. Lambdas were introduced recently but you can't use them with managed code i.e. they are not managed code lambdas but this isn't managed code - ignore any error messages as it does work with COM objects. Under the hoodThe most important thing to realize is that you don't need to know any of the inner workings of the WinRT component to make use of it. WinRT objects are COM objects but their primary interface is IInspectable rather than IUnknown - however IInspetable inherits from IUnknown so you really do have a COM object to work with. WinRT objects are created by an activation factory rather than an object factory. An activation factory has to implement the IActivationFactory interface and the compiler generates one for you automatically. You can use a range of low level functions and templates that have been included in WinRT but it is probably better to leave the compiler to do the job. It also uses QueryInterface to retrieve the interface it needs and AddRef and Release to enable the use count to be maintained. The compiler automatically generates the _IWinRTComponentPublicNonVirtuals interface to provide access to your custom methods. For most of the time you can ignore the fact that you are working with COM but there is one small place where the mechanism breaks the surface. You can use whatever data types you like in the internal workings of your component but data types that are going to be placed in the public interface used to call your object have to be COM datatypes. In many cases the data types are the same but where there is a need new COM data types have been introduced in WinRT. For example, the COM and C++ native string data type are different. If you need to use a string as a return type, parameter or property then it has to be a WinRT string i.e. Platform::String: Platform::String^ MyString="Hello World"; and there are conversion methods to and from standard C++ strings. For example std::MyStdString=MyString->Date(); and Platform::String^ MyCOMString= As well as simple COM types, WinRT also has COM equivalents of more complex data structures, such as collections. This juggling of data types is about the only real complication in creating a WinRT component. Yes, this really is COM and the point is that when you instantiate a WinRT object a lot goes on behind the scenes. For the most part this is best where it stays! |
|||
Last Updated ( Friday, 14 October 2011 ) |