Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   CLR Projections and WinRT Component Type System Rules

WinRT components conform to a type system similar to how the CLR enforces a type system. When the CLR sees a WinRT type, it usually allows that type to be used via the CLRs normal COM interop technologies. But, in some cases, the CLR hides the WinRT type (by dynamically setting it to private) and then the CLR exposes the type via a different type. Internally, the CLR is looking for certain types (via metadata) and then mapping these types to types in the Framework Class Library. For the com- plete list of WinRT types that the CLR implicitly projects to Framework Class Library types, see http:// msdn.microsoft.com/en-us/library/windows/apps/hh995050.aspx.

 

WinRT Type System Core Concepts

The WinRT type system is not as feature rich as the CLR’s type system. This bulleted list describes the WinRT type system’s core concepts and how the CLR projects them:

File names and namespacesThe name of the .winmd file itself must match the name of the namespace containing the WinRT components. For example, a file named Wintellect. WindowsStore.winmd must have WinRT components defined in a Wintellect.Windows­ Store namespace or in a sub-namespace of Wintellect.WindowsStore. Because the Windows file system is case insensitive, namespaces that differ by case only are not allowed. Also, a WinRT component cannot have the same name as a namespace.

Common base typeWinRT components do not share a common base class. When the CLR projects a WinRT type, it appears as if the WinRT type is derived from System.Object and therefore all WinRT types inherit public methods like ToString, GetHashCode, Equals, and GetType. So, when using a WinRT object via C#, the object will look like it is derived from System.Object, and you can pass WinRT objects throughout your code. You can also call the “inherited” methods such as ToString.


Core data typesThe WinRT type system supports the core data types such as Boolean, un- signed byte, 16-bit, 32-bit, and 64-bit signed and unsigned integer numbers, single-precision and double-precision floating-point numbers, 16-bit character, strings, and void.1 Like in the CLR, all other data types are composed from these core data types.

ClassesWinRT is an object-oriented type system, meaning that WinRT components support data abstraction, inheritance, and polymorphism.2 However, some languages (like JavaScript) do not support type inheritance and in order to cater to these languages, almost no WinRT components take advantage of inheritance. This means they also do not take advantage of polymorphism. In fact, only WinRT components consumable from non-JavaScript languages leverage inheritance and polymorphism. For the WinRT components that ship with Windows, only the XAML components (for building user interfaces) take advantage of inheritance and polymorphism. Applications written in JavaScript use HTML and CSS to produce their user interface instead.

StructuresWinRT supports structures (value types), and instances of these are marshaled by value across the COM interoperability boundary. Unlike CLR value types, WinRT structures can only have public fields of the core data types or of another WinRT structure.3 In addition, WinRT structures cannot have any constructors or helper methods. For convenience, the CLR projects some operating system WinRT structures as some native CLR types, which do offer constructors and helper methods. These projected types feel more natural to the CLR devel- oper. Examples include the Point, Rect, Size, and TimeSpan structures all defined in the Windows.Foundation namespace.



Nullable StructuresWinRT APIs can expose nullable structures (value types). The CLR projects the WinRT’s Windows.Foundation.IReference<T> interface as the CLR’s System.Nullable<T> type.

EnumerationsAn enumeration value is simply passed as a signed or unsigned 32-bit inte- ger. If you define an enumeration type in C#, the underlying type must be either int or uint. Also, signed 32-bit integer enums are considered to be discreet values, whereas unsigned

32-bit enums are considered to be flags capable of being OR’d together.

 

InterfacesA WinRT interface’s members must specify only WinRT-compatible types for parameters and return types.

MethodsWinRT has limited support for method overloading. Specifically, because Java- Script has dynamic typing, it can’t distinguish between methods that differ only by the types of their parameters. For example, JavaScript will happily pass a number to a method expecting a string. However, JavaScript can distinguish between a method that takes one parameter and a method that takes two parameters. In addition, WinRT does not support operator overload methods and default argument values. Furthermore, arguments can only be marshaled in or

 

 
 

1 Signed byte is not supported by WinRT.

2 Data abstraction is actually enforced, because WinRT classes are not allowed to have public fields.

3 Enumerations are also OK, because they are really just 32-bit integers.


out; never in and out. This means you can’t apply ref to a method argument but out is OK. For

more information about this, see the “Arrays” bullet point in the next list.

 

PropertiesWinRT properties must specify only WinRT-compatible types for their data type. WinRT does not support parameterful properties or write-only properties.

DelegatesWinRT delegate types must specify only WinRT components for parameter types and return types. When passing a delegate to a WinRT component, the delegate object is wrapped with a CCW and will not get garbage collected until the CCW is released by the WinRT component consuming it. WinRT delegates do not have BeginInvoke and EndInvoke methods.

EventsWinRT components can expose events by using a WinRT delegate type. Because most WinRT components are sealed (no inheritance), WinRT defines a TypedEventHandler delegate where the sender parameter is a generic type (as opposed to System.Object).

 

public delegate void TypedEventHandler<TSender, TResult>(TSender sender, TResult args);

 

There is also a Windows.Foundation.EventHandler<T> WinRT delegate type that the CLR proj- ects as the .NET Framework’s familiar System.EventHandler<T> delegate type.

ExceptionsUnder the covers, WinRT components, like COM components, indicate their sta- tus via HRESULT values (a 32-bit integer with special semantics). The CLR projects WinRT values of type Windows.Foundation.HResult as exception objects. When a WinRT API returns a well-known failure HRESULT value, the CLR throws an instance of a corresponding Exception- derived class. For instance, the HRESULT 0x8007000e (E_OUTOFMEMORY) is mapped to a System.OutOfMemoryException. Other HRESULT values cause the CLR to throw a System. Exception object whose HResult property contains the HRESULT value. A WinRT compo- nent implemented in C# can just throw an exception of a desired type and the CLR will convert it to an appropriate HRESULT value. To have complete control over the HRESULT value, con- struct an exception object, assign a specific HRESULT value in the object’s HResult property, and then throw the object.

StringsOf course, you can pass immutable strings between the WinRT and CLR type sys- tems. However, the WinRT type system doesn’t allow a string to have a value of null. If you pass null to a string parameter of a WinRT API, the CLR detects this and throws an Argument­ NullException; instead, use String.Empty to pass an empty string into a WinRT API. Strings are passed by reference to a WinRT API; they are pinned on the way in and unpinned upon return. Strings are always copied when returned from a WinRT API back to the CLR. When passing a CLR string array (String[]) to or from a WinRT API, a copy of the array is made with all its string elements and the copy is passed or returned to the other side.

Dates and TimesThe WinRT Windows.Foundation.DateTime structure represents a UTC date/time. The CLR projects the WinRT DateTime structure as the .NET Framework’s System.DateTimeOffset structure, because DateTimeOffset is preferred over the .NET Framework’s System.DateTime structure. The CLR converts the UTC date/time being


returned from a WinRT to local time in the resulting DateTimeOffset instance. The CLR passes a DateTimeOffet to a WinRT API as a UTC time.

URIsThe CLR projects the WinRT Windows.Foundation.Uri type as the .NET Framework’s System.Uri type. When passing a .NET Framework Uri to a WinRT API, the CLR throws an ArgumentException if the URI is a relative URI; WinRT supports absolute URIs only. URIs are always copied across the interop boundary.

IClosable/IDisposableThe CLR projects the WinRT Windows.Foundation.IClosable interface (which has only a Close method) as the .NET Framework’s System.IDisposable interface (with its Dispose method). One thing to really take note of here is that all WinRT APIs that perform I/O operations are implemented asynchronously. Because IClosable interface’s method is called Close and is not called CloseAsync, the Close method must not perform any I/O operations. This is semantically different from how Dispose usually works

in the .NET Framework. For .NET Framework-implemented types, calling Dispose can do I/O and, in fact, it frequently causes buffered data to be written before actually closing a device. When C# code calls Dispose on a WinRT type however, I/O (like writing buffered data) will not be performed and a loss of data is possible. You must be aware of this and, for WinRT components that wrap output streams, you will have to explicitly call methods to prevent data loss. For example, when using a DataWriter, you should always call its StoreAsync method.

ArraysWinRT APIs support single-dimension, zero-based arrays. WinRT can marshal an array’s elements in or out of a method; never in and out. Because of this, you cannot pass an array into a WinRT API, have the API modify the array’s elements and then access the modified elements after the API returns.4 I have just described the contract that should be adhered to. However, this contract is not actively enforced, so it is possible that some projections might marshal array contents both in and out. This usually happens naturally due to improving per- formance. For example, if the array contains structures, the CLR will simply pin the array, pass it to the WinRT API, and then unpin it upon return. In effect, the array’s contents are passed in, the WinRT API can modify the contents and, in effect, the modified contents are returned.

However, in this example, the WinRT API is violating the contract and this behavior is not guar- anteed to work. And, in fact, it will not work if the API is invoked on a WinRT component that is running out-of-process.

CollectionsWhen passing a collection to a WinRT API, the CLR wraps the collection object with a CCW and passes a reference to the CCW to the WinRT API. When WinRT code invokes a member on the CCW, the calling thread crosses the interop boundary, thereby incurring a performance hit. Unlike arrays, this means that passing a collection to a WinRT API allows the

API to manipulate the collection in place, and copies of the collection’s elements are not being created. Table 25-1 shows the WinRT collection interfaces and how the CLR projects them to

.NET application code.

 

 
 

4 This means you can’t have an API like System.Array’s Sort method. Interestingly, all the languages (C, C++, C#, Visual Basic, and JavaScript) support passing array elements in and out, but the WinRT type system does not allow this.


TABLE 25-1WinRT Collection Interfaces and Projected CLR Collection Types

 

WinRT Collection Type (Windows.Foundation.Collections namespace) Projected CLR Collection Type (System.Collections.Generic namespace)
IIterable<T> IEnumerable<T>
IVector<T> IList<T>
IVectorView<T> IReadOnlyList<T>
IMap<K, V> IDictionary<TKey, TValue>
IMapView<K, V> IReadOnlyDictionary<TKey, TValue>
IKeyValuePair<K, V> KeyValuePair<TKey, TValue>

 

As you can see from the previous list, the CLR team has done a lot of work to make interoperating between the WinRT type system and the CLR’s type system as seamless as possible so that it is easy for managed code developers to leverage WinRT components in their code.5

 

 


Date: 2016-03-03; view: 1215


<== previous page | next page ==>
Interoperating with WinRT Components | Nbsp;   Framework Projections
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.008 sec.)