Skip to content

Repository files navigation

WinRTWrapper

A wrapper source generator for WinRT

IssuesStargazersNuGet

Support Language

  • C# ISO-2 or later

How to use

  1. Add the NuGet package WinRTWrapper to your project.
  2. Find a class or interface that you want to wrap for WinRT. For example, let's say you have a simple class like this:
    publicsealedclassSimple{publicintProperty{get;set;}publicintMethod()=>Property;publicTaskMethodAsync()=>Task.CompletedTask;publicTaskMethodWithTokenAsync(CancellationTokencancellationToken)=>Task.CompletedTask;publiceventEventHandler<int>?Event;}
  3. Add the GenerateWinRTWrapper attribute to your class or interface that you want to wrap.
    [GenerateWinRTWrapper(typeof(Simple))]publicsealedpartialclassSimpleWrapper;
  4. The source generator will automatically generate a WinRT wrapper for the specified class or interface. You can then use this wrapper in your WinRT applications.
    // <auto-generated/>
    #pragma warning disable
    /// <inheritdoc cref="T:Simple"/>publicsealedpartialclassSimpleWrapper{/// <summary>/// The target <see cref="T:Simple"/> object of the wrapper./// </summary>privatereadonlyglobal::WinRTWrapper.Test.Simpletarget;/// <summary>/// Initializes a new instance of the <see cref="T:SimpleWrapper"/> class with the specified target <see cref="T:Simple"/> object./// </summary>/// <param name="target">The target <see cref="T:Simple"/> object.</param>internalSimpleWrapper(global::WinRTWrapper.Test.Simpletarget){this.target=target;}/// <inheritdoc cref="P:Simple.Property"/>publicintProperty{get{returnthis.target.Property;}set{this.target.Property=value;}}/// <inheritdoc cref="M:Simple.Method"/>publicintMethod(){returnthis.target.Method();}/// <inheritdoc cref="M:Simple.MethodAsync"/>publicglobal::Windows.Foundation.IAsyncActionMethodAsync(){returnglobal::System.WindowsRuntimeSystemExtensions.AsAsyncAction(this.target.MethodAsync());}/// <inheritdoc cref="M:Simple.MethodWithTokenAsync(System.Threading.CancellationToken)"/>publicglobal::Windows.Foundation.IAsyncActionMethodWithTokenAsync(){returnglobal::System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run(delegate(global::System.Threading.CancellationTokencancellationToken){returnthis.target.MethodWithTokenAsync(cancellationToken);});}/// <inheritdoc cref="E:Simple.Event"/>publiceventglobal::System.EventHandler<int>Event{add{this.target.Event+=value;}remove{this.target.Event-=value;}}}

Advanced Usage

Generate Member

You can specify which types of members to generate in the wrapper class by add parameters to the GenerateWinRTWrapper attribute. For example, GenerateMember.Interface will only generate interface members:

[GenerateWinRTWrapper(typeof(Simple),GenerateMember.Interface)]publicsealedpartialclassSimpleWrapper:I;

GenerateMember.Defined will only generate members that are defined in the class:

[GenerateWinRTWrapper(typeof(Simple),GenerateMember.Defined)]publicsealedpartialclassSimpleWrapper{publicpartialintMethod();publicstaticpartialSimpleWrapperGetSelf(SimpleWrapperself);}

You can also specify interfaces which not implemented in the class as a filter:

[GenerateWinRTWrapper(typeof(Simple),typeof(I))]publicsealedpartialclassSimpleWrapper;

Marshaller

You can define a custom marshaller for a specific type by WinRTWrapperMarshaller attribute. A marshaller should implement ConvertToWrapper and ConvertToManaged methods. For example:

[WinRTWrapperMarshaller(typeof(Simple),typeof(SimpleWrapper))]publicsealedpartialclassSimpleWrapper{/// <summary>/// Converts a managed type <see cref="T:WinRTWrapper.Test.Simple"/> to a wrapper type <see cref="T:WinRTWrapper.Test.SimpleWrapper"/>./// </summary>/// <param name="managed">The managed type to convert.</param>/// <returns>The converted wrapper type.</returns>internalstaticglobal::WinRTWrapper.Test.SimpleWrapperConvertToWrapper(global::WinRTWrapper.Test.Simplemanaged){return(global::WinRTWrapper.Test.SimpleWrapper)newglobal::WinRTWrapper.Test.SimpleWrapper(managed);}/// <summary>/// Converts a wrapper type <see cref="T:WinRTWrapper.Test.SimpleWrapper"/> to a managed type <see cref="T:WinRTWrapper.Test.Simple"/>./// </summary>/// <param name="wrapper">The wrapper type to convert.</param>/// <returns>The converted managed type.</returns>internalstaticglobal::WinRTWrapper.Test.SimpleConvertToManaged(global::WinRTWrapper.Test.SimpleWrapperwrapper){return(global::WinRTWrapper.Test.Simple)((global::WinRTWrapper.Test.SimpleWrapper)wrapper).target;}}

It will be generated automatically when both WinRTWrapperMarshaller and GenerateWinRTWrapper attributes are applied to the same class.

Then you can use the WinRTWrapperMarshalUsing attribute to specify the marshaller for a method parameter or return value.

You can apply it to the managed type:

/// <summary>/// Gets a new instance of the <see cref="Simple"/> class with the specified value./// </summary>/// <param name="self">The value to initialize the instance with.</param>/// <returns>The new instance of <see cref="Simple"/>.</returns>[return:WinRTWrapperMarshalUsing(typeof(SimpleWrapper))]publicstaticSimpleGetSelf([WinRTWrapperMarshalUsing(typeof(SimpleWrapper))]Simpleself){returnself;}

Or you can apply it to the wrapper type:

[return:WinRTWrapperMarshalUsing(typeof(SimpleWrapper))]publicstaticpartialSimpleWrapperGetSelf([WinRTWrapperMarshalUsing(typeof(SimpleWrapper))]SimpleWrapperself);

You can also use the WinRTWrapperMarshalling attribute to specify the marshaller for a class.

[WinRTWrapperMarshalling(typeof(SimpleWrapper))]internalclassSimple;

Notice

Since C#/WinRT is not IL/WinRT, you should define every members in the wrapper class. So that the C#/WinRT can generate the correct WinRT metadata for the wrapper class.

Contributors

Contributors

About

A wrapper source generator for WinRT

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages