Chapter 9. An In-Depth Look at Exported Type Libraries

In This Chapter

Converting the Assembly

Converting .NET Data Types

Converting Members

Converting Interfaces

Converting Classes

Converting Value Types

Converting Enumerations

The previous chapter demonstrated how using a .NET component in a COM application can be just like using a COM component, and how type libraries can be created for any .NET component simply by running TLBEXP.EXE (or REGASM.EXE with its /tlb option). In many cases, using the exported type definitions may be self-explanatory, but it is often necessary to gain a deeper understanding of the type library exporter. Even if the author of the .NET component considered the needs of COM users when designing the APIs, it’s unlikely that they are documented from the perspective of an unmanaged C++ or Visual Basic 6 user.

This chapter describes the behavior of the type library exporter in depth. Each element that can be found in an assembly is discussed, one element at a time, in a way that’s similar to Chapter 4, “An In-Depth Look at Imported Assemblies.” As with Chapter 4, this chapter contains several short code listings that demonstrate each transformation. Because both metadata and type library information are stored as binary data, examples need to be shown in representative languages. Most COM examples are shown in Visual Basic 6 and IDL syntax, and most .NET examples are shown in C# and Visual Basic .NET syntax.

The elements that the type library exporter produces—coclasses, interfaces, methods, properties, and so on—are not much different than the elements found in any type library. The exporter knows how to produce type definitions that correspond to the Interop Marshaler’s rules for converting managed types to unmanaged types. These exported type library definitions serve as type information for the COM-Callable Wrappers (CCWs) used at run time. Unlike Interop Assemblies, however, exported type information is not used by the Interop Marshaler at run time; the marshaler always bases its work on metadata definitions.

Converting the Assembly

There is a one-to-one mapping between an assembly and a type library. A single exported type library always contains the appropriate definitions for an entire assembly, even if the assembly consists of multiple files. If the input assembly uses types from additional assemblies in any exported signatures, the exporter automatically generates an additional type library for each referenced assembly. These dependent assemblies must be able to be located when the exporter runs—for example, in the Global Assembly Cache or the current directory.

The generated type library has the name AssemblyName.tlb, where AssemblyName is the assembly’s simple name, unless a different output name is chosen. The most important aspect of the output type library is not its filename, however, but its identity. Type libraries are identified by the following information:

• Library Identifier (LIBID)

• Version

• Locale Identifier (LCID)

If the input assembly isn’t marked with a GuidAttribute custom attribute that chooses a LIBID, the exporter chooses a LIBID based on the input assembly’s simple name, version, and public key. This ensures that assemblies differing by any of this information results in a different LIBID. It also ensures that an assembly’s LIBID remains constant as long as its identity (not counting locale) remains the same.

The exporter uses the assembly’s major and minor version numbers to form the two-part type library version number, unless the major and minor version numbers are both set to zero. In this case, the exported type library is given the version 1.0 because some OLE Automation APIs don’t work properly with a type library version of 0.0. This means that assemblies with version numbers differing only by build or revision numbers end up with the same type library version. Fortunately, the type libraries would still have different identities because their LIBIDs would be different.

The exported type library’s locale identifier (LCID) is set to the default value of zero for assemblies with a neutral culture. For assemblies marked with the System.Reflection. AssemblyCultureAttribute pseudo-custom attribute, the LCID is based on the culture. Every culture has an associated LCID, which can be discovered using System. Globalization.CultureInfo’s LCID property, for example:

// Print the LCID for the French-Canadian culture
Console.WriteLine(new CultureInfo("fr-ca").LCID);

A type library’s LCID can’t be seen when viewed using OLEVIEW.EXE, but can be seen when the type library is registered, since its location is registered under the following key:

HKEY_CLASSES_ROOTTypeLib{LIBID}MajorVersion.MinorVersionLCIDwin32

Although not part of a type library’s identity, the library name is important to clients because Visual C++ and Visual Basic treat it like a namespace. The library name is always the input assembly’s simple name, even if a different output filename is chosen. However, an assembly’s name can contain many characters that are not legal as a type library name, such as periods. Because periods are quite common in assembly names, the exporter converts all periods to underscores. For example, a type library exported for the System.Windows.Forms assembly has the name System_Windows_Forms. Any other special characters (like dollar signs or plus signs) are left alone, but .NET languages (other than IL Assembler) don’t allow them in assembly names anyway.

Although the importer discards library-level helpstrings when creating Interop Assemblies, the exporter marks the library statement with a helpstring for any assemblies marked with the System.Reflection.AssemblyDescriptionAttribute custom attribute, using the attribute’s string contents.

Therefore, an assembly containing the following custom attributes in C# source code (perhaps in an AssemblyInfo.cs file, as generated by Visual Studio .NET):

Image

results in the following exported type library (shown in IDL syntax):

Image

That covers the properties of the output type library. Now we’ll look in depth at how the contents of the type library are produced based on the input assembly.

Converting .NET Data Types

This section covers the data type transformations done by the type library exporter for parameters and return values, and fields of structures. Table 9.1 lists the transformations. These transformations also help summarize the Interop Marshaler’s rules for marshaling .NET types to COM types. As in Chapter 4, each .NET type is shown as the language-neutral type. Keep in mind how the .NET type is typically used in your language of choice (such as int instead of System.Int32). Each COM data type is shown in two representations: IDL and Visual Basic 6.

The Unknown types listed under the “VB6 Type” column is not a real data type in Visual Basic 6, but simply what its object browser shows for IUnknown parameters. This table is a little more complicated than the reverse table in Chapter 4, since .NET data types can be marked with the MarshalAsAttribute pseudo-custom attribute to change their marshaling behavior and therefore their representation in a type library, discussed in Chapter 12, “Customizing COM’s View of .NET Components.” The UnmanagedType values listed represent values inside this attribute. For any data types whose default export/marshaling behavior differs depending on whether they are used as a parameter (including return types) or as a field in an exported structure, both default behaviors are listed separately.

Table 9.1. .NET Data Types Are Converted to COM Data Types with Similar Semantics

Image

Image

Image

Image

Caution

Notice that the exporter treats System.IntPtr, System.UIntPtr, string and array types marked with UnmanagedType.CustomMarshaler, and delegates marked with UnmanagedType.FunctionPtr as int and long data types. This works fine on 32-bit platforms, but such types really represent a platform-sized pointer. If you’re concerned with the exported type library being useable as-is on any platform, you should alter the type library (using tools like OLEVIEW.EXE and MIDL.EXE) to change these ints and longs to void* types.

Table 9.1 assumes that the data types are all COM-visible. Otherwise, COM-invisible reference types are exported as IUnknown* and COM-invisible value types are not exported at all, causing members exposing them to be skipped.

Caution

Unfortunately, a COM-invisible enum parameter is treated just like any other value type. Rather than being replaced with its (COM-visible) underlying type, the member exposing the enum does not get exported at all.

Besides the transformations with and UnmanagedType.CustomMarshaler, UnmanagedType. FunctionPtr, most of the transformations in the table should be self-explanatory. Boolean types are sometimes exported as the long type to represent the Win32 BOOL type. Both are 32-bit types, but BOOL can’t be expressed in a type library. System.Char fields of a struct are exported (and marshaled) depending on the structure’s character set, which is ANSI by default in C#, Visual Basic .NET, and Visual C++ .NET. See Chapter 19, “Deeper Into PInvoke and Useful Examples,” for more information about structures and their character sets. When arrays are exported, their element type may differ based on a MarshalAsAttribute marking that uses SafeArraySubType or ArraySubType, described in Chapter 12.

Caution

In version 1.0 of the CLR, arrays of characters are not exported correctly when marked with UnmanagedType.ByValArray and used as fields of structures with the character set CharSet.Auto. Such a character array field is correctly exported as an array of unsigned char or unsigned short types if the structure has an ANSI or Unicode character set, respectively. However, with a platform-dependent character set, such a field is exported as an array of void types. You should avoid platform-dependent character sets in types exported to a type library, anyway, because the character set of the computer on which the type library is exported may not match the character set of the computer on which a client of the type library is running.

The SomeFormattedClass table entry requires an explanation. A formatted class or formatted reference type is a class that is marked with structure layout using StructLayoutAttribute. Such a reference type gets exported to COM the same way a value type does, but with an extra level of indirection. This means that a formatted class’s fields are exposed to COM, but no methods, properties, or events are. Chapter 19 shows an example of defining and using a formatted class.

Caution

Although the type library exporter converts a structure’s array fields to SAFEARRAYs by default, the Interop Marshaler only supports marshaling SAFEARRAYs as parameters or return types in version 1.0. Therefore, .NET array fields are only exported in a useable way if marked with the MarshalAsAttribute pseudo-custom attribute, covered in Chapter 12.

The exporter only generates three possible kinds of arrays—SAFEARRAYs, fixed-length C-style arrays, and pointers to C-style arrays. There’s no distinction to be made about varying, conformant, or conformant varying since these can’t be expressed in a type library.

Although multidimensional arrays are supported via COM Interoperability, arrays of arrays are not. This means types expressed with [][] in C#. Members using such array types are never exported.

Converting Members

Although COM interfaces have only two types of members (methods and properties), .NET types can have methods (including overloaded methods), properties, fields, and events. Therefore, the type library exporter, following the contract of the Interop Marshaler, performs many different transformations to fit rich .NET object models into the less expressive world of COM.

Although the transformations specific to each member type are discussed in the following sections, one action done by the exporter applies to all member types in a dual interface or dispinterface—choosing DISPIDs. The exporter assigns default DISPIDs, starting with 0x60020000 if none are explicitly assigned. Any default members (such as indexers in C#), which are indicated by the System.Reflection.DefaultMemberAttribute in metadata, are given DISPID 0 (DISPID_VALUE) unless another member is explicitly assigned that DISPID. DISPIDs can be chosen by the author of .NET members by using the DispIdAttribute custom attribute, described in Chapter 12.

Methods

There are six main transformations done by the type library exporter to make .NET method signatures usable and familiar to COM clients:

• Exposing an HRESULT

• Handling [in] versus [out] versus [in, out]

• Handling Overloaded Methods

• Converting ToString

• Converting GetEnumerator

• Converting Parameter Arrays

Exposing an HRESULT

Unless marked with PreserveSigAttribute, a .NET method is transformed so that a return value, if it exists, becomes an [out, retval] parameter, and an HRESULT is returned. This is demonstrated in Listing 9.1.

Listing 9.1. The .NET View and the COM View of the Same Simple Methods

Image

Tip

To see the transformations in Listing 9.1 and the other listings in this chapter for yourself, you’d need to either define the signatures on an interface or on a class marked with the custom attribute ClassInterface(ClassInterfaceType.AutoDual) to see the signatures in the exported library. Otherwise, members of a class are not exposed in the exported auto-dispatch class interfaces. ClassInterface (ClassInterfaceType.AutoDual) should only be used for testing purposes, however.

In the cases where PreserveSigAttribute isn’t used, the returned HRESULT value is always S_OK unless an exception is thrown during the execution of the method. In that case, an HRESULT value corresponding to the exception is returned. Appendix D, “.NET Exception to HRESULT Transformations,” describes these transformations.

Handling [in] Versus [out] Versus [in, out]

When representing parameters of .NET methods as parameters of a COM method, the type library exporter does the following:

• By-value reference type parameters are marked [in]. The only exception to this rule is the System.Text.StringBuilder type because it’s frequently used as an in/out buffer. See Chapter 18, “The Essentials of PInvoke,” for more details. All by-value reference type parameters have one level of indirection except for the reference types listed in the next bullet point.

• By-value value type parameters, strings (when exported as BSTR), arrays (when exported as SAFEARRAY), System.Object (when exported as VARIANT), and types marshaled as void* that are represented as int or long (shown previously in Table 9.1), are always marked [in] and have no levels of indirection.

• All by-reference parameters are marked [in, out] and have one additional level of indirection than they do in the by-value case.

• Pointers to types (as used with C# unsafe code) are exported just like by-reference parameters, but can have extra levels of indirection if the .NET parameter is a pointer to a pointer, and so on. Calling such methods from COM works only when the parameters point to blittable types.

These rules are demonstrated in Listing 9.2.

Listing 9.2. The .NET View and the COM View of the Same Methods with By-Value and By-Reference Parameters

Image

Image

Caution

The fact that reference types are marked and marshaled as [in] by default rather than [in, out] is often unintuitive for .NET programmers when these reference types have layout (as with formatted classes or arrays). This causes only “in” behavior to be observed with Interop marshaling for non-blittable types or COM marshaling across contexts. On the other hand, when managed code calls a managed method with a reference type parameter, “in, out” behavior is always observed. See Chapter 18 for more information.

Chapter 12 shows how a parameter can be marked with either InAttribute or OutAttribute (or both) to change its exported (and, in some cases, marshaling) behavior. If either of the attributes is present, the exporter always does exactly what the attributes dictate even if it doesn’t make sense (such as marking a by-value integer with [out]). This transformation is illustrated in Table 9.2.

Table 9.2. Export Behavior Controlled by InAttribute and OutAttribute

Image

Handling Overloaded Methods

A canonical example of .NET being more expressive than COM is overloaded methods. Although a .NET class or interface can have multiple methods with the same name (as long as each method’s parameters are different), COM interfaces cannot. As mentioned in the previous chapter, the exporter accounts for this by renaming all but the first method by appending _2, _3, and so on, demonstrated in Listing 9.3 with methods exported for System.AppDomain.

Listing 9.3. The .NET View and the COM View of the Same Overloaded Methods

Image

Image

The extra IDL custom attribute on the ExecuteAssembly_2 and ExecuteAssembly_3 methods helps the CLR match the renamed exported members to the original overloads.

Converting ToString

If a .NET class has no default member and no member marked with a DISPID of zero, its ToString method inherited from System.Object is transformed into a property get accessor with a DISPID equal to zero. This transformation is done so it is treated as a default property in COM. As seen in the previous chapter, treating ToString as a default property is pretty natural in Visual Basic 6, especially when you want to “print an object” as if it’s a string. This transformation can be seen when viewing _Object, the class interface for System.Object, in Listing 9.4.

Listing 9.4. The _Object Class Interface

Image

Interestingly enough, any method called ToString, regardless of its signature, is transformed into a property get accessor but not necessarily with a DISPID equal to zero. This method-to-property transformation cannot be suppressed. The extra IDL custom attribute with the GUID 54FC8F55-38DE-4703-9C4E-250351302B1C identifies these exported property get accessors as methods on the .NET side, so the importer handles this transformation correctly when importing a coclass that implements an exported interface with a ToString member. This scenario is the topic of Chapter 17.

Converting GetEnumerator

If a .NET type defines a GetEnumerator method that has no parameters and returns a System.Collections.IEnumerator type, the exporter gives it a DISPID equal to –4 (DISPID_NEWENUM) and transforms the IEnumerator type to the COM IEnumVARIANT interface:

C#:

public IEnumerator GetEnumerator();

IDL:

[id(0xfffffffc)]
HRESULT GetEnumerator([out, retval] IEnumVARIANT** pRetVal);

This is done to make .NET enumerators work seamlessly as COM enumerators, as demonstrated in the previous chapter.

Converting Parameter Arrays

Similar to type library import, the exporter converts .NET parameter arrays to COM parameter arrays, but only if the type of the array is System.Object. This is a requirement of COM, which states that the IDL [vararg] attribute is only valid for a SAFEARRAY with VARIANT elements. This transformation is demonstrated in Listing 9.5.

Listing 9.5. The COM View and the .NET View of Methods with Parameter Arrays

Image

Caution

An exported method with a parameter array (marked with [vararg]) is unusable from Visual Basic 6 since the language requires that parameter arrays be passed by-reference despite the fact that Visual Basic .NET requires parameter arrays to be passed by value. However, unlike the reverse problem when exposing VB6 parameter arrays to Visual Basic .NET, you can’t even treat the parameter array as a regular array parameter—the method is simply unusable!

You cannot define a .NET parameter array as by-reference as an attempt to appease Visual Basic 6 clients. The C# compiler gives error CS1661 (“The params parameter cannot be declared as ref or out”) and the Visual Basic .NET compiler gives error BC30667 (“ParamArray parameters must be declared ‘ByVal’”).

Properties

The transformations done for properties during export aren’t nearly as complicated as the transformations done during import, since normal .NET properties only have one or two accessors. (And if a .NET property has more accessors, such as one written using the IL Assembler, these extra accessors are just treated like regular methods.) The rules are as follows:

• Get accessors are exported as get accessors (propget).

• Set accessors are exported as set accessors (propputref) if the type of the .NET property is a reference type, excluding strings and arrays.

• Set accessors are exported as let accessors (propput) if the type of the .NET property is a value type, string, or array.

Listing 9.6 illustrates these rules.

Listing 9.6. The COM View and the .NET View of Properties

Image

Image

The parameters of the exported property accessors don’t have names, which is why a program like OLEVIEW.EXE might name them pRetVal, whereas Visual Basic 6 names them RHS.

The implication of these property transformations is that you can’t define a .NET System.Object property and have it behave exactly like a VARIANT property as defined in Visual Basic 6, because VB6 generates all three accessors. To write .NET types that behave exactly like existing COM types, you should follow the techniques described in Chapter 14, “Implementing COM Interfaces for Binary Compatibility.”

Fields

In COM, only structs have fields, but in .NET both value types and reference types can have fields. When a struct is exported for a .NET value type or formatted reference type, .NET fields simply become COM fields. But when a class interface is exported for a class with fields, the fields are converted into properties. The rules for this are simple:

• Any field is exposed with a get accessor (propget) and a let accessor (propput) regardless of data type, unless marked as read-only.

• If the field is marked as read-only (readonly in C# and ReadOnly in VB .NET), only a get accessor (propget) is exported.

Listing 9.7 illustrates these rules.

Listing 9.7. The COM View and the .NET View of Fields Exported as Properties

Image

Image

Image

This transformation is similar to fields defined in Visual Basic 6, which are actually exposed as COM properties.

Events

Strictly speaking, there’s no such thing as an “event” in COM. Therefore, when an interface for a class contains an event member, the exporter exposes its two accessor methods for adding and removing event handlers. This is shown in Listing 9.8.

Listing 9.8. The COM View and the .NET View of an Event

Image

The next chapter explains why these methods are not very useful to COM clients wishing to hookup event handlers. Chapter 13, “Exposing .NET Events to COM Clients,” explains how authors of .NET APIs can expose events to COM in a more natural way.

Converting Interfaces

Converting public, COM-visible .NET interfaces to COM interfaces is straightforward once you understand the member conversions just discussed. The exporter produces three kinds of interfaces—those that don’t derive from IDispatch (IUnknown-only interfaces), dual interfaces, and dispinterfaces. All .NET interfaces are dual unless marked otherwise with the InterfaceTypeAttribute discussed in Chapter 12. Like LIBIDs, exported interfaces are given automatically-generated IIDs if the .NET definitions aren’t marked with GuidAttribute custom attributes.

Any types exported to a type library—interfaces, classes, structures, enums—are given their simple .NET type names that exclude their namespaces. If the same assembly contains multiple public types with the same name but in separate namespaces, each exported type name becomes Namespace_TypeName to avoid duplicate definitions. (This renaming is still done even if only one of the conflicting types is exported due to the others being marked COM-invisible.) As with assembly names being converted to library names, any periods in the namespace (or :: in Visual C++ .NET) are converted to underscores.

As with importing, there’s a subtle aspect to exporting interfaces that derive from other interfaces. When exporting an inheritance hierarchy of .NET interfaces, the resultant COM interfaces appear as unrelated “slices,” containing only the members defined directly on them. This is shown in Listing 9.9.

Listing 9.9. The C# Representation of Two Interfaces Related by Inheritance, and the IDL Representation of the Exported Interfaces

Image

Image

Because both interfaces derive directly from IDispatch, a COM user can’t directly call a member like MoveNext directly on an IDictionaryEnumerator type. Instead, a C++ client must call IUnknown.QueryInterface to get an IEnumerator interface pointer, and a Visual Basic 6 client must declare a new variable of type IEnumerator and set the reference of the IDictionaryEnumerator type to it (causing a QueryInterface call).

Converting Classes

Public COM-visible .NET classes are exported as coclasses (unless they are formatted classes). Because coclasses themselves don’t have members, a class interface is often generated and implemented by the coclass. An automatically-generated class interface always has the name _CoclassName and is always marked as dual, but by default lists no members since they can only be invoked via late binding.

So, rather than listing members, coclasses in a type library list interfaces that they implement (although usually not all interfaces). A coclass exported from a .NET class lists all the public COM-visible interfaces that the corresponding .NET class implements, all the public COM-visible interfaces implemented by its base classes, plus any class interfaces exposed for the class or its base classes. An exported coclass is marked with the IDL [noncreatable] attribute if the .NET class doesn’t have a public default constructor or is marked as abstract (MustInherit in VB .NET), so COM clients know that they can’t attempt to create an instance of it. Listing 9.10 demonstrates the transformation from .NET classes to COM classes. Besides the class interfaces, each coclass lists _Object as an implemented interface since that’s the class interface for the .NET classes’ System.Object base class.

Listing 9.10. Two .NET Classes and Their Exported IDL Coclass Representation

Image

Image

Whenever a formatted .NET class is converted to a struct, the exporter issues a warning because it might catch users of the exported type library by surprise. The transformation for a formatted class is the same as the transformation for a value type, described in the next section.

Converting Value Types

Value types are exported as structs (UDTs) in a type library. Although value types can contain methods—even implement interfaces—only its fields are exposed to COM since type library structs don’t have the same capabilities. As listed in Table 9.1, data types exported as fields of structs undergo different conversion rules than data types exported as parameters or return types. Listing 9.11 shows an example.

Listing 9.11. Two .NET Classes and Their Exported IDL Coclass Representation

Image

In this contrived example, notice how the methods are omitted from the COM structs. Also notice that private fields are exposed just like public fields! There is no way to hide fields of a structure from COM, either via .NET visibility or attempting to restrict COM visibility, since to COM a structure’s layout is critical for proper operation. In many cases, the problems caused by lack of a value type’s methods being exposed to COM are mitigated by the fact that the underlying non-public representation can be directly manipulated.

The type library exporter generates a union instead of a plain struct for any .NET types marked with StructLayout(LayoutKind.Explicit) whose fields are all marked with a memory offset of zero.

Caution

If any value types are marked with StructLayout(LayoutKind.Auto), the exporter silently treats them the same as value types with sequential layout. However, attempting to use such structs in COM may fail in subtle ways because the CLR is free to rearrange the layout at any time. You can check what kind of layout a .NET value type has by opening its assembly with the IL Disassembler (ILDASM.EXE) and looking at the first entry under the value type’s node. It will either say auto, sequential, or explicit, the first of which should never be used from unmanaged code.

Converting Enumerations

Converting .NET enumerations to COM enumerations is not as straightforward as the reverse. One complication is that enums defined in a type library can only have a 32-bit underlying type, whereas .NET enums can have any integral underlying type. For any .NET enumeration, regardless of underlying type, the exporter creates a 32-bit enumeration with the same values. If an enum has a 64-bit underlying type, however, and it contains at least one value that doesn’t fit in 32 bits, type library export fails with a message like the following:

Type library exporter encountered an error while processing  'BigEnum.BigValue, MyAssembly'. Error: The enum member  BigEnum.BigEnum_BigValue has a value which can not be expressed  as a 32-bit integer. Type library enum members must be 32-bit integers.

It would be incorrect for .NET signatures with non-32-bit enum parameters to be exported as COM signatures with enum parameters, since the exported enums are 32-bit. Therefore, any such parameters are exported as their underlying types instead. This transformation is listed in Table 9.1 at the beginning of the chapter. Because the enumeration type might still appear in the type library, COM clients can still use it to convert to and from the integral values passed as parameters.

A second complication involves the name of enumeration members. Every enum member is named EnumName_MemberName rather than just MemberName. These transformations are demonstrated in Listing 9.12, including the transformations done when enums are used as parameters.

Listing 9.12. The C# Representation of Enumerations and Enumeration Parameters, and the IDL Representation of These Exported Types

Image

Image

Image

Image

Image

Notice that the exported SetWeekDay and SetSpeed methods use the exported WeekDays and Speeds enumerations, but the other methods’ parameters are replaced with the non-32-bit underlying types.

Conclusion

This chapter covered all the major details of how COM type information is generated from .NET type information. These transformations are the key to .NET objects being easily usable in COM applications without requiring special effort on the part of the .NET programmer. With the type library exporter, a COM client can see interfaces, coclasses, structs, enums, and unions representing .NET entities. The exporter never produces type library modules or typedefs.

This chapter is a complement to Part IV, which is all about designing .NET components so that they are exposed to COM in the most natural way possible. The exporter’s transformations are meant to work best for components that follow .NET guidelines and conventions, but you’ve seen cases where typical .NETisms like overloaded methods and event members don’t get exposed nicely by default.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset