Merge pull request #3 from microsoft/work_with_winui

Work with winui
This commit is contained in:
Scott Jones 2019-10-24 18:25:17 -07:00 коммит произвёл GitHub
Родитель 781dbe87e9 bda825a5b4
Коммит 464586f2ab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
22 изменённых файлов: 715 добавлений и 682 удалений

15
Directory.Build.targets Normal file
Просмотреть файл

@ -0,0 +1,15 @@
<!--NOTE: Directory.Build.* files are temporary until C#/WinRT nuget contains msbuild support-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ResolveAssemblyReferencesDependsOn Condition="'$(RemoveWindowsReference)'=='true'">$(ResolveAssemblyReferencesDependsOn);RemoveWindowsReference</ResolveAssemblyReferencesDependsOn>
</PropertyGroup>
<!--Remove Windows.Winmd reference to prevent compile collisions-->
<Target Name="RemoveWindowsReference" Outputs="@(Reference)">
<ItemGroup>
<Reference Remove="Windows"/>
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props')" />
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<ProjectGuid>{7e3a9ab3-8cbb-4b9c-ba76-0fe7108dcaeb}</ProjectGuid>
@ -91,13 +91,13 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.190605.7\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.191018.6\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

Просмотреть файл

@ -1,27 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resources">
<UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="Class.cpp" />
<ClCompile Include="module.g.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="Class.idl" />
</ItemGroup>
<ItemGroup>
<None Include="TestComp.def" />
<None Include="packages.config" />
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resources">
<UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="Class.cpp" />
<ClCompile Include="module.g.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="Class.idl" />
</ItemGroup>
<ItemGroup>
<None Include="TestComp.def" />
<None Include="packages.config" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.190605.7" targetFramework="native" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.191018.6" targetFramework="native" />
</packages>

Просмотреть файл

@ -0,0 +1,6 @@
<!--NOTE: Directory.Build.* files are temporary until C#/WinRT nuget contains msbuild support-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
</Project>

Просмотреть файл

@ -0,0 +1,22 @@
<!--NOTE: Directory.Build.* files are temporary until C#/WinRT nuget contains msbuild support-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildTestProjection Condition="'$(BuildTestProjection)$(Configuration)' == 'Release'">true</BuildTestProjection>
</PropertyGroup>
<Target Name="CopyTestComponent" BeforeTargets="PreBuildEvent">
<Exec Command="xcopy /D /Y &quot;$(OutDir)TestComp\TestComp.dll&quot; &quot;$(TargetDir)&quot;" />
<Exec Command="xcopy /D /Y &quot;$(OutDir)TestComp\TestComp.pdb&quot; &quot;$(TargetDir)&quot;" />
</Target>
<Target Name="ProjectTestComponent" BeforeTargets="CoreCompile" Condition="'$(BuildTestProjection)' == 'true'">
<Exec Command="$(CsWinrtExe) -verbose -in $(OutDir)TestComp\TestComp.winmd 10.0.18362.0 -out &quot;$(ProjectDir)Generated Files&quot; -include TestComp -include Windows.Foundation -exclude Windows.Foundation.Diagnostics -exclude Windows.Foundation.Metadata" />
<ItemGroup>
<Compile Include="$(ProjectDir)Generated Files/*.cs" Exclude="@(Compile)" />
</ItemGroup>
</Target>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />
</Project>

Просмотреть файл

@ -31,7 +31,7 @@ namespace TestComp.Manual
public struct Vftbl
{
#pragma warning disable 0169 // warning CS0169: The field '...' is never used
WinRT.Interop.IInspectableVftbl IInspectableVftbl;
WinRT.IInspectable.Vftbl IInspectableVftbl;
#pragma warning restore 0169
#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to
public WinRT.Interop._add_EventHandler add_Event0;
@ -106,14 +106,14 @@ namespace TestComp.Manual
// both exclusive and polymorphic (e.g. IStringable)
// demonstrating 'casting' an interface back to its RC (constructing from IUnknown -> exclusive)
// object equivalence via IUnknown, etc
(IntPtr value) => (obj.ThisPtr == value) ? Owner : ObjectReference<Vftbl>.FromNativePtr(value),
(IntPtr value) => (obj.ThisPtr == value) ? Owner : ObjectReference<Vftbl>.FromNative(value),
(IntPtr value) => new MarshaledValue<Int32>(value).UnmarshalFromNative());
_StringPropertyChanged =
new EventSource<Class, HString>(_obj,
_obj.Vftbl.add_StringPropertyChanged,
_obj.Vftbl.remove_StringPropertyChanged,
(IntPtr value) => (obj.ThisPtr == value) ? (Class)Owner : new Class(ObjectReference<Vftbl>.FromNativePtr(value)),
(IntPtr value) => (obj.ThisPtr == value) ? (Class)Owner : new Class(ObjectReference<Vftbl>.FromNative(value)),
(IntPtr value) => new MarshaledValue<HString>(value).UnmarshalFromNative());
}

Просмотреть файл

@ -7,8 +7,6 @@
<Platforms>AnyCPU;x64;x86</Platforms>
<ApplicationManifest>app1.manifest</ApplicationManifest>
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>
@ -16,27 +14,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NoWarn>1701;1702;0436;1658</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<NoWarn>1701;1702;0436;1658</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;0436;1658</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<NoWarn>1701;1702;0436;1658</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NoWarn>1701;1702;0436;1658</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<PropertyGroup>
<NoWarn>1701;1702;0436;1658</NoWarn>
</PropertyGroup>
@ -53,23 +31,8 @@
<ProjectReference Include="..\TestComp\TestComp.vcxproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Windows">
<HintPath>$(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.17763.0\Windows.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
</Reference>
<ItemGroup>
<Folder Include="Generated Files\" />
</ItemGroup>
<Target Name="CopyTestComponent" BeforeTargets="PreBuildEvent">
<Exec Command="xcopy /D /Y &quot;$(OutDir)TestComp\TestComp.dll&quot; &quot;$(TargetDir)&quot;" />
<Exec Command="xcopy /D /Y &quot;$(OutDir)TestComp\TestComp.pdb&quot; &quot;$(TargetDir)&quot;" />
</Target>
<Target Name="ProjectTestComponent" BeforeTargets="CoreCompile" Condition="'$(BuildTestProjection)' == 'true'">
<Exec Command="$(CsWinrtExe) -verbose -in $(OutDir)TestComp\TestComp.winmd local -out &quot;$(ProjectDir)Generated Files&quot; -include TestComp -include Windows.Foundation -exclude Windows.Foundation.Diagnostics -exclude Windows.Foundation.Metadata" />
<ItemGroup>
<Compile Include="$(ProjectDir)Generated Files/*.cs" Exclude="@(Compile)" />
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -9,11 +9,9 @@ using WinRT;
using WF = Windows.Foundation;
using WFC = Windows.Foundation.Collections;
using WFM = Windows.Foundation.Metadata;
using WFN = Windows.Foundation.Numerics;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Foundation.Metadata;
using Windows.Foundation.Numerics;
using TestComp;
@ -22,9 +20,8 @@ using TestComp;
namespace UnitTest
{
using A = IIterable<IStringable>;
using B = IKeyValuePair<string, IAsyncOperationWithProgress</*A*/IIterable<IStringable>, float>>;
using IInspectable = ObjectReference<WinRT.Interop.IInspectableVftbl>; // todo
using B = IKeyValuePair<string, IAsyncOperationWithProgress</*A*/IIterable<IStringable>, float>>;
public class TestGuids
{
private static void AssertGuid<T>(string expected)
@ -101,11 +98,11 @@ namespace UnitTest
}
}
public class TestCompTests
public class TestComponent
{
public Class TestObject { get; private set; }
public TestCompTests()
public TestComponent()
{
TestObject = new Class();
}
@ -124,9 +121,9 @@ namespace UnitTest
public void TestPrimitives()
{
var test_int = 21;
TestObject.IntPropertyChanged += (Object sender, Int32 value) =>
TestObject.IntPropertyChanged += (IInspectable sender, Int32 value) =>
{
var c = (Class)sender;
var c = Class.FromNative(sender.NativePtr);
Assert.Equal(value, test_int);
};
TestObject.IntProperty = test_int;

Просмотреть файл

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!--<file name="TestComp.dll">
<activatableClass
name="TestComp.Class"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>-->
</assembly>

Просмотреть файл

@ -0,0 +1,6 @@
<!--NOTE: Directory.Build.* files are temporary until C#/WinRT nuget contains msbuild support-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
</Project>

Просмотреть файл

@ -0,0 +1,38 @@
<!--NOTE: Directory.Build.* files are temporary until C#/WinRT nuget contains msbuild support-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildTestProjection Condition="'$(BuildTestProjection)$(Configuration)' == 'Release'">true</BuildTestProjection>
</PropertyGroup>
<Target Name="ProjectWinUI" BeforeTargets="CoreCompile" Condition="'$(BuildTestProjection)' == 'true'">
<ItemGroup>
<!--PkgMicrosoft_UI_Xaml is defined by Nuget reference-->
<WinUIWinMDs Include="$(PkgMicrosoft_UI_Xaml)/**/*.winmd" />
</ItemGroup>
<PropertyGroup>
<CsWinRTVerbosity>high</CsWinRTVerbosity>
<CsWinRTResponseFile>$(IntDir)cswinrt_platform.rsp</CsWinRTResponseFile>
<CsWinRTCommand>$(CsWinrtExe) %40"$(CsWinRTResponseFile)"</CsWinRTCommand>
</PropertyGroup>
<PropertyGroup>
<CsWinRTParams>
-verbose
-in 10.0.18362.0 @(WinUIWinMDs->'&quot;%(FullPath)&quot;', ' ')
-out &quot;$(ProjectDir)Generated Files&quot;
-include Microsoft Windows
</CsWinRTParams>
</PropertyGroup>
<WriteLinesToFile
File="$(CsWinRTResponseFile)" Lines="$(CsWinRTParams)"
Overwrite="true" WriteOnlyWhenDifferent="true" />
<Message Text="$(CsWinRTCommand)" Importance="$(CsWinRTVerbosity)"/>
<Exec Command="$(CsWinRTCommand)" />
<ItemGroup>
<Compile Include="$(ProjectDir)Generated Files/*.cs" Exclude="@(Compile)" />
</ItemGroup>
</Target>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />
</Project>

Просмотреть файл

@ -0,0 +1,8 @@
{
"profiles": {
"UnitTest": {
"commandName": "Project",
"nativeDebugging": false
}
}
}

28
WinUITest/Test.cs Normal file
Просмотреть файл

@ -0,0 +1,28 @@
// WinUI projection smoke test (compile only)
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using Xunit;
using WinRT;
using Windows.Foundation;
using Windows.Foundation.Collections;
namespace WinUITest
{
public class TestProjection
{
public TestProjection()
{
}
[Fact]
public void TestSomeWinUI()
{
// TODO: load up some MUX!
//Assert.Equal(true, true);
}
}
}

Просмотреть файл

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
<Platforms>AnyCPU;x64;x86</Platforms>
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<NoWarn>1701;1702;0436;1658</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="Microsoft.UI.Xaml" Version="3.0.0-alpha.191024.2" />
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.1-rc" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="XunitXml.TestLogger" Version="2.1.26" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\cswinrt\cswinrt.vcxproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Generated Files\" />
</ItemGroup>
</Project>

14
WinUITest/readme.txt Normal file
Просмотреть файл

@ -0,0 +1,14 @@
This project simply generates and compiles a complete projection of Windows SDK and WinUI metadata.
With a release cswinrt.exe, it takes < 1s to generate all of the projection sources.
With debug, it takes a minute. So only release builds create the projection by default.
This can be overridden by explicitly setting the BuildTestProjection property.
This project assumes a private nuget source has been created, pointing to:
https://microsoft.pkgs.visualstudio.com/_packaging/WinUI-Xaml-CI@IXP/nuget/v3/index.json
For usability (until the cswinrt nuget has msbuild support), this and the UnitTest projects
both make use of Directory.Build.* files to create the projection, stage binaries, etc.
WinUITest uses a response file to generate the projection, which can be supplied as a
debugging parameter to the cswinrt project.

Просмотреть файл

@ -12,6 +12,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTe
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cswinrt", "cswinrt\cswinrt.vcxproj", "{6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUITest", "WinUITest\WinUITest.csproj", "{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Files", "Build Files", "{96495AB4-2D86-47D1-A174-27D0B436DC98}"
ProjectSection(SolutionItems) = preProject
build.cmd = build.cmd
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -64,6 +73,22 @@ Global
{6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|x64.Build.0 = Release|x64
{6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|x86.ActiveCfg = Release|Win32
{6ACFD2B2-E8AA-4CD4-AAD8-213CE8BB2637}.Release|x86.Build.0 = Release|Win32
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|ARM.ActiveCfg = Debug|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|ARM.Build.0 = Debug|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|x64.ActiveCfg = Debug|x64
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|x64.Build.0 = Debug|x64
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|x86.ActiveCfg = Debug|x86
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Debug|x86.Build.0 = Debug|x86
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|Any CPU.Build.0 = Release|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|ARM.ActiveCfg = Release|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|ARM.Build.0 = Release|Any CPU
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|x64.ActiveCfg = Release|x64
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|x64.Build.0 = Release|x64
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|x86.ActiveCfg = Release|x86
{AD0BD44A-D9B5-419C-90D0-B017AEE09C85}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -34,7 +34,7 @@ namespace cswinrt
switch (value.Type())
{
case ConstantType::Int32:
w.write_printf("%d", value.ValueInt32());
w.write_printf("%#0x", value.ValueInt32());
break;
case ConstantType::UInt32:
w.write_printf("%#0x", value.ValueUInt32());
@ -126,10 +126,44 @@ namespace cswinrt
w.write("@", type.TypeName());
}
void write_type_params(writer& w, TypeDef const& type)
{
if (distance(type.GenericParam()) == 0)
{
return;
}
separator s{ w };
uint32_t index = 0;
w.write("<%>", bind_each([&](writer& w, GenericParam const& /*gp*/)
{ s(); write_generic_type_name(w, index++); }, type.GenericParam()));
}
void write_type_name(writer& w, type_semantics const& semantics)
{
auto write_name = [&](TypeDef const& type)
{
write_typedef_name(w, type);
write_type_params(w, type);
};
call(semantics,
[&](type_definition const& type){ write_name(type); },
[&](generic_type_instance const& type)
{
auto guard{ w.push_generic_args(type) };
write_name(type.generic_type);
},
[](auto){ throw_invalid("invalid type"); });
}
auto write_type_name_temp(writer& w, type_semantics const& type, char const* format = "%")
{
return w.write_temp(format, bind<write_type_name>(type));
}
void write_projection_type(writer& w, type_semantics const& semantics)
{
call(semantics,
[&](object_type) { w.write("object"); },
[&](object_type) { w.write("IInspectable"); },
[&](guid_type) { w.write("Guid"); },
[&](type_definition const& type) { write_typedef_name(w, type); },
[&](generic_type_index const& var) { write_generic_type_name(w, var.index); },
@ -148,44 +182,6 @@ namespace cswinrt
bind_list<write_projection_type>(", ", type.generic_args));
}
void write_type_params(writer& w, TypeDef const& type)
{
if (distance(type.GenericParam()) == 0)
{
return;
}
separator s{ w };
uint32_t index = 0;
w.write("<%>", bind_each([&](writer& w, GenericParam const& /*gp*/)
{ s(); write_generic_type_name(w, index++); }, type.GenericParam()));
}
void write_full_type_name(writer& w, type_semantics const& semantics, bool include_namespace = false)
{
auto write_name = [&](TypeDef const& type)
{
if (include_namespace)
{
w.write("%.", type.TypeNamespace());
}
w.write("@", type.TypeName());
write_type_params(w, type);
};
call(semantics,
[&](type_definition const& type){ write_name(type); },
[&](generic_type_instance const& type)
{
auto guard{ w.push_generic_args(type) };
write_name(type.generic_type);
},
[](auto){ throw_invalid("invalid type"); });
}
void write_type_name(writer& w, type_semantics const& semantics)
{
write_full_type_name(w, semantics);
}
void write_type_inheritance(writer& w, TypeDef const& type)
{
bool first{ true };
@ -241,11 +237,11 @@ namespace cswinrt
w.write("%", bind<write_projection_type>(type));
}
},
[](auto) { throw_invalid("invalid interface impl type"); });
[](auto) { throw_invalid("invalid interface impl type"); });
}
}
void write_parameter_name(writer& w, method_signature::param_t const& param)
void write_parameter_name_with_modifier(writer& w, method_signature::param_t const& param, bool with_modifier = true)
{
static const std::set<std::string_view> keywords = {
"abstract", "as", "base", "bool", "break", "byte",
@ -267,9 +263,26 @@ namespace cswinrt
w.write("@");
}
if (with_modifier)
{
switch (get_param_category(param))
{
case param_category::out:
w.write("out ");
break;
default:
break;
}
}
w.write(param.first.Name());
}
void write_parameter_name(writer& w, method_signature::param_t const& param)
{
write_parameter_name_with_modifier(w, param, false);
}
void write_iid_field(writer& w, TypeDef const& type)
{
auto attribute = get_attribute(type, "Windows.Foundation.Metadata", "GuidAttribute");
@ -308,7 +321,7 @@ namespace cswinrt
void write_projection_param_type(writer& w, type_semantics const& semantics)
{
call(semantics,
[&](object_type) { w.write("object"); },
[&](object_type) { w.write("IInspectable"); },
[&](guid_type) { w.write("Guid"); },
[&](type_definition const& type) { write_typedef_name(w, type); },
[&](generic_type_index const& var)
@ -385,7 +398,7 @@ namespace cswinrt
{
case category::enum_type:
{
w.write("Int32");
write_type_name(w, type);
break;
}
case category::struct_type:
@ -710,18 +723,30 @@ namespace cswinrt
write_event_params(w, evt, write_params);
}
void write_delegate_extension_call(writer& w, TypeDef const& type, std::string_view call, std::string_view name)
{
w.write("%Extensions%.%(%)",
bind<write_typedef_name>(type),
bind<write_type_params>(type),
call, name);
}
void write_object_marshal_from_native(writer& w, type_semantics const& param_type, TypeDef const& type, std::string_view name, bool is_boxed = false)
{
switch (get_category(type))
{
case category::enum_type:
{
w.write("(%)%%", bind<write_type_name>(type), is_boxed ? "(object)" : "", name);
if (is_boxed)
{
w.write("(%)", bind<write_type_name>(type));
}
w.write("%", name);
return;
}
case category::delegate_type:
{
w.write("@Extensions%.FromNative(%)", type.TypeName(), bind<write_type_params>(type), name);
write_delegate_extension_call(w, type, "FromNative", name);
return;
}
case category::struct_type:
@ -768,18 +793,21 @@ namespace cswinrt
}
}
std::string_view const OwnerMemberName = "_WinRT_Owner";
void write_event_param_marshaler(writer& w, method_signature::param_t const& param)
{
std::function<void(type_semantics const&)> write_type = [&](type_semantics const& semantics) {
call(semantics,
[&](object_type)
{
w.write("(IntPtr value) => (obj.ThisPtr == value) ? Owner : ObjectReference<Vftbl>.FromNativePtr(value)");
{
w.write("(IntPtr value) => (obj.ThisPtr == value) ? (IInspectable)% : IInspectable.FromNative(value)", OwnerMemberName);
},
[&](type_definition const& type)
{
w.write(R"((IntPtr value) => (obj.ThisPtr == value) ? (%)Owner : %)",
w.write(R"((IntPtr value) => (obj.ThisPtr == value) ? (%)% : %)",
bind<write_projection_param_type>(semantics),
OwnerMemberName,
bind<write_object_marshal_from_native>(semantics, type, "value"sv, true));
},
[&](generic_type_index const& var)
@ -789,8 +817,9 @@ namespace cswinrt
[&](generic_type_instance const& type)
{
auto guard{ w.push_generic_args(type) };
w.write(R"((IntPtr value) => (obj.ThisPtr == value) ? (%)Owner : %)",
w.write(R"((IntPtr value) => (obj.ThisPtr == value) ? (%)% : %)",
bind<write_projection_param_type>(semantics),
OwnerMemberName,
bind<write_object_marshal_from_native>(semantics, type.generic_type, "value"sv, true));
},
[&](fundamental_type const& type)
@ -1007,7 +1036,7 @@ public %% %(%)
signature.return_signature() ? "return " : "",
interface_member,
method.Name(),
bind_list<write_parameter_name>(", ", signature.params())
bind_list<write_parameter_name_with_modifier>(", ", signature.params(), true)
);
}
@ -1055,8 +1084,8 @@ remove => %.% -= value;
}
auto default_interface = get_default_interface(type);
auto default_interface_name = w.write_temp("%", bind<write_type_name>(get_type_semantics(default_interface)));
auto type_name = w.write_temp("%", bind<write_type_name>(type));
auto default_interface_name = write_type_name_temp(w, get_type_semantics(default_interface));
auto type_name = write_type_name_temp(w, type);
w.write(R"(public %class %
{
public IntPtr NativePtr { get => _default.NativePtr; }
@ -1065,12 +1094,12 @@ private % _default;
public %() : this(ActivationFactory<%>.ActivateInstance<%.Vftbl>()){}
public static % FromNative(IntPtr ^@this) => new %(ObjectReference<%.Vftbl>.FromNativePtr(^@this));
public static % FromNative(IntPtr ^@this) => new %(WinRT.ObjectReference<%.Vftbl>.FromNative(^@this));
internal %(% ifc)
{
_default = ifc;
_default.Owner = this;
_default.% = this;
}
)",
bind<write_class_modifiers>(type),
@ -1083,7 +1112,8 @@ _default.Owner = this;
type_name,
default_interface_name,
type_name,
default_interface_name);
default_interface_name,
OwnerMemberName);
for (auto&& ii : type.InterfaceImpl())
{
@ -1093,7 +1123,7 @@ _default.Owner = this;
{
if( !is_exclusive_to(interface_type) )
{
auto interface_name = w.write_temp("%", bind<write_full_type_name>(interface_type, true));
auto interface_name = write_type_name_temp(w, interface_type);
w.write(
R"(
public static implicit operator %(% obj) =>
@ -1128,7 +1158,7 @@ public static implicit operator %(% obj) =>
// w.write("public %class %%\n{\n",
// bind<write_class_modifiers>(type),
// bind<write_type_name>(type),
// bind<write_type_name>(type, false),
// bind<write_type_inheritance>(type));
// {
// w.write("static Lazy<IntPtr> _factory = new Lazy<IntPtr>(() => Windows.Foundation.IActivationFactory.Get(\"%.%\"));\n",
@ -1206,8 +1236,10 @@ public static implicit operator %(% obj) =>
get<uint8_t>(get_arg(10)));
}
void write_vtbl_entry(writer& w, MethodDef const& method, int vtbl_index)
void write_vtbl_entry(writer& w, MethodDef const& method, uint32_t vtbl_base)
{
XLANG_ASSERT(vtbl_base <= method.index());
uint32_t const vtbl_index = method.index() - vtbl_base;
auto get_delegate_type = [&]() -> std::string
{
method_signature signature{ method };
@ -1232,14 +1264,9 @@ public static implicit operator %(% obj) =>
{
switch (get_category(type))
{
case category::enum_type:
{
suffix = "Int32";
break;
}
case category::struct_type:
{
suffix = w.write_temp("<%>", bind<write_type_name>(type));
suffix = write_type_name_temp(w, type, "<%>");
break;
}
default:
@ -1265,7 +1292,7 @@ public static implicit operator %(% obj) =>
}
}
auto delegate_type = w.write_temp("_%%", method.Name(), vtbl_index);
auto delegate_type = w.write_temp("_%_%", method.Name(), vtbl_index);
w.write("public %delegate int %([In] %);\n",
is_unsafe(signature) ? "unsafe " : "",
delegate_type,
@ -1274,26 +1301,30 @@ public static implicit operator %(% obj) =>
return delegate_type;
};
w.write("public %% %;\n",
(method.Name() == "ToString"sv || method.Name() == "Equals"sv) ? "new " : "",
w.write("public % %_%;\n",
get_delegate_type(),
method.Name());
method.Name(),
vtbl_index);
}
void write_event_source_ctors(writer& w, TypeDef const& type)
{
uint32_t const vtbl_base = type.MethodList().first.index();
for (auto&& evt : type.EventList())
{
auto [add, remove] = get_event_methods(evt);
w.write(R"(
_% =
new EventSource%(_obj,
_obj.Vftbl.add_%,
_obj.Vftbl.remove_%%);)",
_obj.Vftbl.add_%_%,
_obj.Vftbl.remove_%_%%);)",
evt.Name(),
bind<write_event_param_types>(evt),
evt.Name(),
add.index() - vtbl_base,
evt.Name(),
remove.index() - vtbl_base,
bind<write_event_param_marshalers>(evt));
}
}
@ -1315,7 +1346,7 @@ private EventSource% _%;)",
call(semantics,
[&](object_type)
{
w.write("ObjectReference<WinRT.Interop.IInspectableVftbl>.FromNativePtr(%)", name);
w.write("IInspectable.FromNative(%)", name);
},
[&](type_definition const& type)
{
@ -1353,12 +1384,12 @@ private EventSource% _%;)",
{
case category::enum_type:
{
w.write("(Int32)%", name);
w.write("%", name);
return;
}
case category::delegate_type:
{
w.write("@Extensions%.ToNative(%)", type.TypeName(), bind<write_type_params>(type), name);
write_delegate_extension_call(w, type, "ToNative", name);
return;
}
case category::struct_type:
@ -1380,7 +1411,7 @@ private EventSource% _%;)",
call(semantics,
[&](object_type)
{
w.write("/* todo %.NativePtr */ IntPtr.Zero", name);
w.write("%.NativePtr", name);
},
[&](type_definition const& type)
{
@ -1407,13 +1438,44 @@ private EventSource% _%;)",
write_type(semantics);
}
bool is_native_out_object(type_semantics const& semantics)
bool is_type_blittable(type_semantics const& semantics)
{
return call(semantics,
[&](object_type) { return true; },
[&](type_definition const& /*type*/) { return true; },
[&](generic_type_instance const& /*type*/) { return true; },
[&](auto) { return false; });
[&](object_type)
{
return false;
},
[&](type_definition const& type)
{
switch (get_category(type))
{
case category::enum_type:
{
return true;
}
case category::struct_type:
{
// TODO: non-blittable fields
return true;
}
default:
{
return false;
}
}
},
[&](generic_type_instance const& /*type*/)
{
return false;
},
[&](fundamental_type const& type)
{
return (type != fundamental_type::String);
},
[&](auto)
{
return true;
});
}
void write_param_out_local_declare(writer& w, method_signature::param_t const& param)
@ -1424,7 +1486,7 @@ private EventSource% _%;)",
{
case param_category::out:
{
if (is_native_out_object(get_type_semantics(param.second->Type())))
if(!is_type_blittable(get_type_semantics(param.second->Type())))
{
w.write("IntPtr %_value;\n", bind<write_parameter_name>(param));
}
@ -1452,14 +1514,9 @@ private EventSource% _%;)",
{
switch (get_category(type))
{
case category::enum_type:
{
// w.write("(%)%%", bind<write_type_name>(type), is_boxed ? "(object)" : "", name);
return;
}
case category::delegate_type:
{
w.write("@Extensions%.FromNative(%)", type.TypeName(), bind<write_type_params>(type), name);
write_delegate_extension_call(w, type, "FromNative", name);
return;
}
case category::struct_type:
@ -1484,7 +1541,7 @@ private EventSource% _%;)",
call(semantics,
[&](object_type)
{
w.write("ObjectReference<WinRT.Interop.IInspectableVftbl>.FromNativePtr(%)", name);
w.write("IInspectable.FromNative(%)", name);
},
[&](type_definition const& type)
{
@ -1499,8 +1556,12 @@ private EventSource% _%;)",
auto guard{ w.push_generic_args(type) };
write_object_out_marshal_from_native(w, semantics, type.generic_type, name);
},
[&](fundamental_type const& /*type*/)
[&](fundamental_type const& type)
{
if (type == fundamental_type::String)
{
w.write(R"(new WinRT.HString(%))", name);
}
//write_fundamental_marshal_from_native(w, type, name);
},
[&](auto)
@ -1555,7 +1616,7 @@ private EventSource% _%;)",
w.write("out %%", bind<write_parameter_name>(param),
bind([&](writer& w)
{
if (is_native_out_object(get_type_semantics(param.second->Type())))
if (!is_type_blittable(get_type_semantics(param.second->Type())))
{
w.write("_value");
}
@ -1582,6 +1643,7 @@ private EventSource% _%;)",
void write_interface_members(writer& w, TypeDef const& type,
std::function<void(writer& w, std::string_view name, std::string_view type)> write_custom)
{
uint32_t const vtbl_base = type.MethodList().first.index();
for (auto&& method : type.MethodList())
{
if (is_special(method))
@ -1598,7 +1660,7 @@ private EventSource% _%;)",
w.write(R"(
public %% %(%)
{
%%%unsafe { Marshal.ThrowExceptionForHR(_obj.Vftbl.%(NativePtr%%)); }%%
%%%unsafe { Marshal.ThrowExceptionForHR(_obj.Vftbl.%_%(NativePtr%%)); }%%
})",
(method.Name() == "ToString"sv) ? "new " : "",
bind<write_method_return>(signature),
@ -1616,6 +1678,7 @@ public %% %(%)
bind<write_interop_type>(get_type_semantics(signature.return_signature().Type()))) :
"",
method.Name(),
method.index() - vtbl_base,
bind_each([](writer& w, auto const& param)
{
w.write(", %", bind<write_param_marshal_to_native>(param));
@ -1651,7 +1714,7 @@ public % %
w.write(R"(get
{
%% __return_value__;
unsafe { Marshal.ThrowExceptionForHR(_obj.Vftbl.get_%(NativePtr, out __return_value__)); }
unsafe { Marshal.ThrowExceptionForHR(_obj.Vftbl.get_%_%(NativePtr, out __return_value__)); }
return %;
}
)",
@ -1663,13 +1726,14 @@ return %;
}),
bind<write_interop_type>(semantics),
prop.Name(),
getter.index() - vtbl_base,
bind<write_marshal_from_native>(semantics, "__return_value__"));
}
if (setter)
{
w.write(R"(set
{
%unsafe { Marshal.ThrowExceptionForHR(_obj.Vftbl.put_%(NativePtr, %)); }
%unsafe { Marshal.ThrowExceptionForHR(_obj.Vftbl.put_%_%(NativePtr, %)); }
}
)",
bind([&](writer& w) {
@ -1679,6 +1743,7 @@ return %;
}
}),
prop.Name(),
setter.index() - vtbl_base,
bind<write_marshal_to_native>(semantics, "value"));
}
if (!custom.empty())
@ -1710,10 +1775,12 @@ remove => _%.Event -= value;
{
XLANG_ASSERT(get_category(type) == category::interface_type);
auto type_name = w.write_temp("%", bind<write_type_name>(type));
auto type_name = write_type_name_temp(w, type);
auto is_generic = distance(type.GenericParam()) > 0;
// TODO: temporary strategy for generating generics, until all can be automated,
// and hardcoded unique suffixes (vtbl offsets) removed from names.
static const struct
{
std::string_view type_name;
@ -1731,7 +1798,7 @@ remove => _%.Event -= value;
{
"IIterator`1"sv,
R"(public WinRT.Interop._get_PropertyAsObject get_CurrentAsObject;)"sv,
R"(get_CurrentAsObject = typeof(T).IsClass ? _obj.Vftbl.get_Current.AsDelegate<WinRT.Interop._get_PropertyAsObject>() : null;)"sv,
R"(get_CurrentAsObject = typeof(T).IsClass ? _obj.Vftbl.get_Current_0.AsDelegate<WinRT.Interop._get_PropertyAsObject>() : null;)"sv,
[](writer& w, std::string_view name, std::string_view)
{
if (name == "Current"sv)
@ -1749,8 +1816,8 @@ return marshaler_T.FromNative(__return_value__);
"IKeyValuePair`2"sv,
R"(public WinRT.Interop._get_PropertyAsObject get_KeyAsObject;
public WinRT.Interop._get_PropertyAsObject get_ValueAsObject;)"sv,
R"(get_KeyAsObject = typeof(K).IsClass ? _obj.Vftbl.get_Key.AsDelegate<WinRT.Interop._get_PropertyAsObject>() : null;
get_ValueAsObject = typeof(V).IsClass ? _obj.Vftbl.get_Value.AsDelegate<WinRT.Interop._get_PropertyAsObject>() : null;)"sv,
R"(get_KeyAsObject = typeof(K).IsClass ? _obj.Vftbl.get_Key_0.AsDelegate<WinRT.Interop._get_PropertyAsObject>() : null;
get_ValueAsObject = typeof(V).IsClass ? _obj.Vftbl.get_Value_1.AsDelegate<WinRT.Interop._get_PropertyAsObject>() : null;)"sv,
[](writer& w, std::string_view name, std::string_view type)
{
if (name == "Key"sv && type == "get"sv)
@ -1781,7 +1848,7 @@ return marshaler_V.FromNative(__return_value__);
{
"IMapChangedEventArgs`1"sv,
R"(public WinRT.Interop._get_PropertyAsObject get_KeyAsObject;)"sv,
R"(get_KeyAsObject = typeof(K).IsClass ? _obj.Vftbl.get_Key.ToGetPropertyAsObject() : null;)"sv,
R"(get_KeyAsObject = typeof(K).IsClass ? _obj.Vftbl.get_Key_1.ToGetPropertyAsObject() : null;)"sv,
[](writer& w, std::string_view name, std::string_view type)
{
if (name == "Key"sv && type == "get"sv)
@ -1810,21 +1877,21 @@ R"(if (typeof(V).IsClass)
{
if (typeof(K).IsClass)
{
Lookup__ = _obj.Vftbl.Lookup.AsDelegate<_Lookup__>();
Lookup__ = _obj.Vftbl.Lookup_0.AsDelegate<_Lookup__>();
}
else
{
LookupK_ = _obj.Vftbl.Lookup.AsDelegate<_LookupK_>();
LookupK_ = _obj.Vftbl.Lookup_0.AsDelegate<_LookupK_>();
}
}
else if (typeof(K).IsClass)
{
Lookup_V = _obj.Vftbl.Lookup.AsDelegate<_Lookup_V>();
Lookup_V = _obj.Vftbl.Lookup_0.AsDelegate<_Lookup_V>();
}
if (typeof(K).IsClass)
{
HasKey_ = _obj.Vftbl.HasKey.AsDelegate<_HasKey_>();
})"sv,
HasKey_ = _obj.Vftbl.HasKey_2.AsDelegate<_HasKey_>();
})"sv,
[](writer& w, std::string_view name, std::string_view /*type*/)
{
if (name == "Lookup"sv)
@ -1884,12 +1951,12 @@ private delegate int _Append_([In] IntPtr @this, IntPtr value);
private _Append_ Append_;)"sv,
R"(if (typeof(T).IsClass)
{
GetAt_ = _obj.Vftbl.GetAt.AsDelegate<_GetAt_>();
IndexOf_ = _obj.Vftbl.IndexOf.AsDelegate<_IndexOf_>();
SetAt_ = _obj.Vftbl.SetAt.AsDelegate<_SetAt_>();
InsertAt_ = _obj.Vftbl.InsertAt.AsDelegate<_InsertAt_>();
Append_ = _obj.Vftbl.Append.AsDelegate<_Append_>();
})"sv,
GetAt_ = _obj.Vftbl.GetAt_0.AsDelegate<_GetAt_>();
IndexOf_ = _obj.Vftbl.IndexOf_3.AsDelegate<_IndexOf_>();
SetAt_ = _obj.Vftbl.SetAt_4.AsDelegate<_SetAt_>();
InsertAt_ = _obj.Vftbl.InsertAt_5.AsDelegate<_InsertAt_>();
Append_ = _obj.Vftbl.Append_7.AsDelegate<_Append_>();
})"sv,
[](writer& w, std::string_view name, std::string_view /*type*/)
{
if (name == "GetAt"sv)
@ -1941,9 +2008,9 @@ private unsafe delegate int _IndexOf_([In] IntPtr @this, IntPtr value, out uint
private _IndexOf_ IndexOf_;)"sv,
R"(if (typeof(T).IsClass)
{
GetAt_ = _obj.Vftbl.GetAt.AsDelegate<_GetAt_>();
IndexOf_ = _obj.Vftbl.IndexOf.AsDelegate<_IndexOf_>();
})"sv,
GetAt_ = _obj.Vftbl.GetAt_0.AsDelegate<_GetAt_>();
IndexOf_ = _obj.Vftbl.IndexOf_2.AsDelegate<_IndexOf_>();
})"sv,
[](writer& w, std::string_view name, std::string_view /*type*/)
{
if (name == "GetAt"sv)
@ -1999,7 +2066,7 @@ R"()"sv
}) : nullptr;
XLANG_ASSERT(!is_generic || (generic_helper != std::end(generic_helpers)));
int vtbl_index = 0;
uint32_t const vtbl_base = type.MethodList().first.index();
w.write(R"(%
% class %%
{
@ -2007,7 +2074,7 @@ R"()"sv
public struct Vftbl
{
#pragma warning disable 0169 // warning CS0169: The field '...' is never used
WinRT.Interop.IInspectableVftbl IInspectableVftbl;
WinRT.IInspectable.Vftbl IInspectableVftbl;
#pragma warning restore 0169
#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to
%#pragma warning restore 0649
@ -2015,16 +2082,16 @@ WinRT.Interop.IInspectableVftbl IInspectableVftbl;
%private readonly WinRT.ObjectReference<Vftbl> _obj;
public IntPtr NativePtr { get => _obj.ThisPtr; }
public static ObjectReference<Vftbl> FromNative(IntPtr ^@this) => ObjectReference<Vftbl>.FromNativePtr(^@this);
public static WinRT.ObjectReference<Vftbl> FromNative(IntPtr ^@this) => WinRT.ObjectReference<Vftbl>.FromNative(^@this);
public static implicit operator %(WinRT.IObjectReference obj) => obj.As<Vftbl>();
public static implicit operator %(WinRT.ObjectReference<Vftbl> obj) => new %(obj);
public ObjectReference<I> As<I>() => _obj.As<I>();
public WinRT.ObjectReference<I> As<I>() => _obj.As<I>();
public @(WinRT.ObjectReference<Vftbl> obj)
{
_obj = obj;%%
}
public object Owner { get; set; }
public object % { get; set; }
%%
}
)",
@ -2037,7 +2104,7 @@ public object Owner { get; set; }
bind<write_guid_attribute>(type),
bind_each([&](writer& w, MethodDef const& method)
{
write_vtbl_entry(w, method, vtbl_index++);
write_vtbl_entry(w, method, vtbl_base);
}, type.MethodList()),
bind([&](writer& w) {
if (!is_generic) return;
@ -2083,6 +2150,7 @@ R"(public static readonly Marshaler<%> marshaler_% = typeof(%).IsClass ? new Mar
w.write("\n%", generic_helper->init_delegate_casts);
}),
bind<write_event_source_ctors>(type),
OwnerMemberName,
bind<write_interface_members>(type, generic_helper ? generic_helper->write_custom : nullptr),
bind<write_event_sources>(type)
);
@ -2136,6 +2204,19 @@ invoke(%);
return;
}
static auto write_object_marshal = [&](writer& w, TypeDef const& type)
{
switch (get_category(type))
{
case category::interface_type:
case category::class_type:
{
w.write(".NativePtr");
return;
}
}
};
w.write(
R"({
% __result = default;
@ -2143,21 +2224,38 @@ var __hresult = WinRT.Delegate.MarshalInvoke(^@this, (% invoke) =>
{
__result = invoke(%)%;
});
result = __result;
% = __result;
return __hresult;
})",
bind<write_interop_type>(get_type_semantics(return_sig.Type())),
type_name,
bind_list<write_delegate_param_marshal>(", ", signature.params()),
bind([&](writer &w){
auto semantics = get_type_semantics(return_sig.Type());
auto rt = std::get_if<fundamental_type>(&semantics);
if (!rt || (*rt != fundamental_type::String))
return;
if (!return_sig.Type().is_szarray())
{
w.write(".Handle");
}
call(get_type_semantics(return_sig.Type()),
[&](object_type)
{
w.write(".NativePtr");
},
[&](type_definition const& type)
{
write_object_marshal(w, type);
},
[&](generic_type_instance const& type)
{
auto guard{ w.push_generic_args(type) };
write_object_marshal(w, type.generic_type);
},
[&](fundamental_type const& type)
{
if ((type == fundamental_type::String) && !return_sig.Type().is_szarray())
{
w.write(".Handle");
}
},
[](auto){});
}),
bind([&](writer& w) {
w.write("%", signature.return_param_name());
}));
};
@ -2165,7 +2263,7 @@ return __hresult;
{
method_signature signature{ get_delegate_invoke(type) };
auto type_name = w.write_temp("%", bind<write_type_name>(type));
auto type_name = write_type_name_temp(w, type);
auto type_params = w.write_temp("%", bind<write_type_params>(type));
w.write(R"(public delegate % %(%);
@ -2177,7 +2275,7 @@ private unsafe delegate int Native_Invoke(%);
public static unsafe % FromNative(IntPtr ^@this)
{
var nativeDelegate = ObjectReference<WinRT.Interop.IDelegateVftbl>.FromNativePtr(^@this);
var nativeDelegate = ObjectReference<WinRT.Interop.IDelegateVftbl>.FromNative(^@this);
% managedDelegate =
(%) =>
{
@ -2255,46 +2353,44 @@ public static Guid PIID = GuidGenerator.CreateIID(typeof(%));)",
w.write("}\n");
}
void write_type(TypeDef const& type)
std::string_view get_database_name(winmd::reader::database const& database)
{
if (is_api_contract_type(type)) { return; }
if (is_attribute_type(type)) { return; }
writer w(type.TypeNamespace());
auto guard{ w.push_generic_params(type.GenericParam()) };
w.write(R"(// This file was generated by cswinrt.exe
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using WinRT;
namespace %
{
)", type.TypeNamespace());
const auto &path = database.path();
auto idx = path.rfind('\\'); // TODO: Handle xplat path seperators.
if (idx == std::string::npos
|| idx + 1 >= path.size())
{
switch (get_category(type))
{
case category::class_type:
write_class(w, type);
break;
case category::delegate_type:
write_delegate(w, type);
break;
case category::enum_type:
write_enum(w, type);
break;
case category::interface_type:
write_interface(w, type);
break;
case category::struct_type:
write_struct(w, type);
break;
}
return { path };
}
w.write("}\n");
auto filename = w.write_temp("%.@.cs", type.TypeNamespace(), type.TypeName());
w.flush_to_file(settings.output_folder / filename);
return { path.data() + idx + 1 };
}
bool write_type(TypeDef const& type, writer& w)
{
if (is_api_contract_type(type)) { return false; }
if (is_attribute_type(type)) { return false; }
auto guard{ w.push_generic_params(type.GenericParam()) };
switch (get_category(type))
{
case category::class_type:
write_class(w, type);
break;
case category::delegate_type:
write_delegate(w, type);
break;
case category::enum_type:
write_enum(w, type);
break;
case category::interface_type:
write_interface(w, type);
break;
case category::struct_type:
write_struct(w, type);
break;
}
return true;
}
}

Просмотреть файл

@ -130,13 +130,6 @@ Where <spec> is one or more of:
task_group group;
//group.add([]
//{
// writer w;
// w.write(strings::base_interop);
// w.flush_to_file(settings.output_folder / "base-interop.cs");
//});
group.add([]
{
writer w;
@ -145,18 +138,28 @@ Where <spec> is one or more of:
w.flush_to_file(settings.output_folder / "WinRT.cs");
});
for (auto&&[ns, members] : c.namespaces())
for (auto&& ns_members : c.namespaces())
{
for (auto&&[name, type] : members.types)
group.add([&ns_members]
{
if (settings.filter.includes(type))
auto&& [ns, members] = ns_members;
writer w(ns);
w.write_begin();
bool written{};
for (auto&& [name, type] : members.types)
{
group.add([&type]
if (settings.filter.includes(type))
{
write_type(type);
});
written |= write_type(type, w);
};
}
}
if (written)
{
w.write_end();
auto filename = w.write_temp("%.cs", ns);
w.flush_to_file(settings.output_folder / filename);
}
});
}
group.get();

Просмотреть файл

@ -5,17 +5,17 @@ namespace cswinrt
using namespace std::literals;
using namespace winmd::reader;
template <typename T>
bool has_attribute(T const& row, std::string_view const& type_namespace, std::string_view const& type_name)
{
return static_cast<bool>(get_attribute(row, type_namespace, type_name));
}
template <typename T>
bool has_attribute(T const& row, std::string_view const& type_namespace, std::string_view const& type_name)
{
return static_cast<bool>(get_attribute(row, type_namespace, type_name));
}
//template <typename T>
//auto get_attribute_value(CustomAttribute const& attribute, uint32_t const arg)
//{
// return std::get<T>(std::get<ElemSig>(attribute.Value().FixedArgs()[arg].value).value);
//}
//template <typename T>
//auto get_attribute_value(CustomAttribute const& attribute, uint32_t const arg)
//{
// return std::get<T>(std::get<ElemSig>(attribute.Value().FixedArgs()[arg].value).value);
//}
bool is_exclusive_to(TypeDef const& type)
{
@ -37,15 +37,15 @@ namespace cswinrt
return get_category(type) == category::class_type && extends_type(type, "System"sv, "Attribute"sv);
}
bool is_ptype(TypeDef const& type)
{
return distance(type.GenericParam()) > 0;
}
bool is_ptype(TypeDef const& type)
{
return distance(type.GenericParam()) > 0;
}
bool is_static(TypeDef const& type)
{
return get_category(type) == category::class_type && type.Flags().Abstract();
}
bool is_static(TypeDef const& type)
{
return get_category(type) == category::class_type && type.Flags().Abstract();
}
bool is_constructor(MethodDef const& method)
{
@ -57,10 +57,10 @@ namespace cswinrt
return method.SpecialName() || method.Flags().RTSpecialName();
}
bool is_static(MethodDef const& method)
{
return method.Flags().Static();
}
bool is_static(MethodDef const& method)
{
return method.Flags().Static();
}
auto get_delegate_invoke(TypeDef const& type)
{
@ -223,28 +223,28 @@ namespace cswinrt
{
return get_type_semantics(type);
},
[](GenericTypeIndex var) -> type_semantics {
[](GenericTypeIndex var) -> type_semantics {
return generic_type_index{ var.index }; },
[](GenericTypeInstSig sig) -> type_semantics {
[](GenericTypeInstSig sig) -> type_semantics {
return get_type_semantics(sig); },
[](GenericMethodTypeIndex) -> type_semantics { throw_invalid("Generic methods not supported"); }
}, signature.Type());
}
TypeDef get_typedef(type_semantics const& semantics)
{
return std::visit(
impl::overloaded{
[](type_definition type) { return type; },
[](generic_type_instance type_instance) { return type_instance.generic_type; },
[](auto) -> TypeDef { throw_invalid("type doesn't contain typedef"); }
}, semantics);
};
TypeDef get_typedef(type_semantics const& semantics)
{
return std::visit(
impl::overloaded{
[](type_definition type) { return type; },
[](generic_type_instance type_instance) { return type_instance.generic_type; },
[](auto) -> TypeDef { throw_invalid("type doesn't contain typedef"); }
}, semantics);
};
TypeDef get_typedef(coded_index<TypeDefOrRef> const& type)
{
return get_typedef(get_type_semantics(type));
};
TypeDef get_typedef(coded_index<TypeDefOrRef> const& type)
{
return get_typedef(get_type_semantics(type));
};
struct method_signature
{
@ -371,9 +371,9 @@ namespace cswinrt
}
}
XLANG_ASSERT(get_method);
XLANG_ASSERT(get_method || set_method);
if (set_method)
if (get_method && set_method)
{
XLANG_ASSERT(get_method.Flags().Static() == set_method.Flags().Static());
}
@ -381,122 +381,122 @@ namespace cswinrt
return std::make_tuple(get_method, set_method);
}
auto get_event_methods(Event const& evt)
{
MethodDef add_method{}, remove_method{};
auto get_event_methods(Event const& evt)
{
MethodDef add_method{}, remove_method{};
for (auto&& method_semantic : evt.MethodSemantic())
{
auto semantic = method_semantic.Semantic();
for (auto&& method_semantic : evt.MethodSemantic())
{
auto semantic = method_semantic.Semantic();
if (semantic.AddOn())
{
add_method = method_semantic.Method();
}
else if (semantic.RemoveOn())
{
remove_method = method_semantic.Method();
}
else
{
throw_invalid("Events can only have add and remove methods");
}
}
if (semantic.AddOn())
{
add_method = method_semantic.Method();
}
else if (semantic.RemoveOn())
{
remove_method = method_semantic.Method();
}
else
{
throw_invalid("Events can only have add and remove methods");
}
}
XLANG_ASSERT(add_method);
XLANG_ASSERT(remove_method);
XLANG_ASSERT(add_method.Flags().Static() == remove_method.Flags().Static());
XLANG_ASSERT(add_method);
XLANG_ASSERT(remove_method);
XLANG_ASSERT(add_method.Flags().Static() == remove_method.Flags().Static());
return std::make_tuple(add_method, remove_method);
}
return std::make_tuple(add_method, remove_method);
}
struct activation_factory
{
TypeDef type;
};
struct activation_factory
{
TypeDef type;
};
struct static_factory
{
TypeDef type;
};
struct static_factory
{
TypeDef type;
};
// TODO: composable factory
// TODO: composable factory
using factory_info = std::variant<activation_factory, static_factory>;
using factory_info = std::variant<activation_factory, static_factory>;
auto get_factories(TypeDef const& type)
{
auto get_system_type = [&](FixedArgSig const& fixed_arg, bool optional = false) -> TypeDef
{
if (auto type_param = std::get_if<ElemSig::SystemType>(&std::get<ElemSig>(fixed_arg.value).value))
{
return type.get_cache().find_required(type_param->name);
}
if (optional)
{
return {};
}
auto get_factories(TypeDef const& type)
{
auto get_system_type = [&](FixedArgSig const& fixed_arg, bool optional = false) -> TypeDef
{
if (auto type_param = std::get_if<ElemSig::SystemType>(&std::get<ElemSig>(fixed_arg.value).value))
{
return type.get_cache().find_required(type_param->name);
}
throw_invalid("Invalid factory argument");
};
if (optional)
{
return {};
}
std::vector<factory_info> result;
throw_invalid("Invalid factory argument");
};
for (auto&& attribute : type.CustomAttribute())
{
auto attribute_name = attribute.TypeNamespaceAndName();
std::vector<factory_info> result;
if (attribute_name.first != "Windows.Foundation.Metadata")
{
continue;
}
for (auto&& attribute : type.CustomAttribute())
{
auto attribute_name = attribute.TypeNamespaceAndName();
auto fixed_args = attribute.Value().FixedArgs();
if (attribute_name.first != "Windows.Foundation.Metadata")
{
continue;
}
if (attribute_name.second == "ActivatableAttribute")
{
activation_factory info{ get_system_type(fixed_args[0], true) };
result.push_back(std::move(info));
}
else if (attribute_name.second == "StaticAttribute")
{
static_factory info{ get_system_type(fixed_args[0], true) };
XLANG_ASSERT((bool)info.type);
result.push_back(std::move(info));
}
else if (attribute_name.second == "ComposableAttribute")
{
throw_invalid("ComposableAttribute not implemented");
//info.type = get_system_type(fixed_args[0]);
//info.composable = true;
auto fixed_args = attribute.Value().FixedArgs();
//auto compositionType = std::get<ElemSig::EnumValue>(std::get<ElemSig>(fixed_args[1].value).value);
//info.visible = std::get<int32_t>(compositionType.value) == 2;
}
}
if (attribute_name.second == "ActivatableAttribute")
{
activation_factory info{ get_system_type(fixed_args[0], true) };
result.push_back(std::move(info));
}
else if (attribute_name.second == "StaticAttribute")
{
static_factory info{ get_system_type(fixed_args[0], true) };
XLANG_ASSERT((bool)info.type);
result.push_back(std::move(info));
}
else if (attribute_name.second == "ComposableAttribute")
{
throw_invalid("ComposableAttribute not implemented");
//info.type = get_system_type(fixed_args[0]);
//info.composable = true;
return std::move(result);
}
//auto compositionType = std::get<ElemSig::EnumValue>(std::get<ElemSig>(fixed_args[1].value).value);
//info.visible = std::get<int32_t>(compositionType.value) == 2;
}
}
return std::move(result);
}
static coded_index<TypeDefOrRef> get_default_interface(TypeDef const& type)
{
auto impls = type.InterfaceImpl();
{
auto impls = type.InterfaceImpl();
for (auto&& impl : impls)
{
if (has_attribute(impl, "Windows.Foundation.Metadata", "DefaultAttribute"))
{
return impl.Interface();
}
}
for (auto&& impl : impls)
{
if (has_attribute(impl, "Windows.Foundation.Metadata", "DefaultAttribute"))
{
return impl.Interface();
}
}
if (!empty(impls))
{
throw_invalid("Type '", type.TypeNamespace(), ".", type.TypeName(), "' does not have a default interface");
}
if (!empty(impls))
{
throw_invalid("Type '", type.TypeNamespace(), ".", type.TypeName(), "' does not have a default interface");
}
return {};
}
return {};
}
}

Просмотреть файл

@ -26,7 +26,6 @@ namespace WinRT
namespace Interop
{
// IUnknown
[Guid("00000000-0000-0000-C000-000000000046")]
public struct IUnknownVftbl
{
@ -39,27 +38,13 @@ namespace WinRT
public _Release Release;
}
// IInspectable
[Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")]
public struct IInspectableVftbl
{
public delegate int _GetIids([In] IntPtr pThis, [Out] uint iidCount, [Out] Guid[] iids);
public delegate int _GetRuntimeClassName([In] IntPtr pThis, [Out] IntPtr className);
public delegate int _GetTrustLevel([In] IntPtr pThis, [Out] TrustLevel trustLevel);
public IUnknownVftbl IUnknownVftbl;
public _GetIids GetIids;
public _GetRuntimeClassName GetRuntimeClassName;
public _GetTrustLevel GetTrustLevel;
}
// IActivationFactory
[Guid("00000035-0000-0000-C000-000000000046")]
public struct IActivationFactoryVftbl
{
public unsafe delegate int _ActivateInstance([In] IntPtr pThis, [Out] out IntPtr instance);
public IInspectableVftbl IInspectableVftbl;
public IInspectable.Vftbl IInspectableVftbl;
public _ActivateInstance ActivateInstance;
}
@ -98,12 +83,12 @@ namespace WinRT
//public delegate int _put_PropertyAsString([In] IntPtr thisPtr, [In, MarshalAs(UnmanagedType.HString)] string value);
public unsafe delegate int _get_PropertyAsString([In] IntPtr thisPtr, [Out] out IntPtr value);
public delegate int _put_PropertyAsString([In] IntPtr thisPtr, [In] IntPtr value);
public unsafe delegate int _get_PropertyAsVector3([In] IntPtr thisPtr, [Out] out Vector3 value);
public delegate int _put_PropertyAsVector3([In] IntPtr thisPtr, [In] Vector3 value);
public unsafe delegate int _get_PropertyAsQuaternion([In] IntPtr thisPtr, [Out] out Quaternion value);
public delegate int _put_PropertyAsQuaternion([In] IntPtr thisPtr, [In] Quaternion value);
public unsafe delegate int _get_PropertyAsMatrix4x4([In] IntPtr thisPtr, [Out] out Matrix4x4 value);
public delegate int _put_PropertyAsMatrix4x4([In] IntPtr thisPtr, [In] Matrix4x4 value);
public unsafe delegate int _get_PropertyAsVector3([In] IntPtr thisPtr, [Out] out Windows.Foundation.Numerics.Vector3 value);
public delegate int _put_PropertyAsVector3([In] IntPtr thisPtr, [In] Windows.Foundation.Numerics.Vector3 value);
public unsafe delegate int _get_PropertyAsQuaternion([In] IntPtr thisPtr, [Out] out Windows.Foundation.Numerics.Quaternion value);
public delegate int _put_PropertyAsQuaternion([In] IntPtr thisPtr, [In] Windows.Foundation.Numerics.Quaternion value);
public unsafe delegate int _get_PropertyAsMatrix4x4([In] IntPtr thisPtr, [Out] out Windows.Foundation.Numerics.Matrix4x4 value);
public delegate int _put_PropertyAsMatrix4x4([In] IntPtr thisPtr, [In] Windows.Foundation.Numerics.Matrix4x4 value);
public unsafe delegate int _add_EventHandler([In] IntPtr thisPtr, [In] IntPtr handler, [Out] out WinRT.Interop.EventRegistrationToken token);
public delegate int _remove_EventHandler([In] IntPtr thisPtr, [In] WinRT.Interop.EventRegistrationToken token);
@ -120,78 +105,36 @@ namespace WinRT
{
public long Value;
}
#if false
// IReference
[Guid("dacbffdc-68ef-5fd0-b657-782d0ac9807e")]
public struct IReference_Matrix4x4
}
// IInspectable
[Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")]
public class IInspectable
{
[Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")]
public struct Vftbl
{
IInspectableVftbl IInspectableVftbl;
public _get_PropertyAsMatrix4x4 get_Value;
public delegate int _GetIids([In] IntPtr pThis, [Out] uint iidCount, [Out] Guid[] iids);
public delegate int _GetRuntimeClassName([In] IntPtr pThis, [Out] IntPtr className);
public delegate int _GetTrustLevel([In] IntPtr pThis, [Out] TrustLevel trustLevel);
public Interop.IUnknownVftbl IUnknownVftbl;
public _GetIids GetIids;
public _GetRuntimeClassName GetRuntimeClassName;
public _GetTrustLevel GetTrustLevel;
}
// IIterator
public struct IIteratorOfObject
private readonly WinRT.ObjectReference<Vftbl> _obj;
public IntPtr NativePtr { get => _obj.ThisPtr; }
public static WinRT.ObjectReference<Vftbl> FromNative(IntPtr @this) => WinRT.ObjectReference<Vftbl>.FromNative(@this);
public static implicit operator IInspectable(WinRT.IObjectReference obj) => obj.As<Vftbl>();
public static implicit operator IInspectable(WinRT.ObjectReference<Vftbl> obj) => new IInspectable(obj);
public WinRT.ObjectReference<I> As<I>() => _obj.As<I>();
public IInspectable(WinRT.ObjectReference<Vftbl> obj)
{
public unsafe delegate int _MoveNext([In] IntPtr thisPtr, [Out, MarshalAs(UnmanagedType.Bool)] out bool hasCurrent);
public unsafe delegate int _GetMany([In] IntPtr thisPtr, [In] uint capacity, [In] ref IntPtr[] values, [Out] out uint actual);
public IInspectableVftbl IInspectableVftbl;
public _get_PropertyAsObject get_Current;
public _get_PropertyAsBoolean get_HasCurrent;
public _MoveNext MoveNext;
public _GetMany GetMany;
_obj = obj;
}
public struct IIterableOfObject
{
public IInspectableVftbl IInspectableVftbl;
public _get_PropertyAsObject get_First;
}
public struct IVectorViewOfObject
{
public unsafe delegate int _GetAt([In] IntPtr thisPtr, [In] uint index, [Out] out IntPtr result);
public unsafe delegate int _IndexOf([In] IntPtr thisPtr, [In] IntPtr value, [Out] out uint index, [Out, MarshalAs(UnmanagedType.Bool)] out bool found);
public unsafe delegate int _GetMany([In] IntPtr thisPtr, [In] uint startingIndex, [In] uint capacity, [In] ref IntPtr[] values, [Out] out uint actual);
public IInspectableVftbl IInspectableVftbl;
public _GetAt GetAt;
public _get_PropertyAsUInt32 get_Size;
public _IndexOf IndexOf;
public _GetMany GetMany;
}
public struct IIteratorOfByte
{
public unsafe delegate int _MoveNext([In] IntPtr thisPtr, [Out, MarshalAs(UnmanagedType.Bool)] out bool hasCurrent);
public unsafe delegate int _GetMany([In] IntPtr thisPtr, [In] uint capacity, [In] ref byte[] values, [Out] out uint actual);
public IInspectableVftbl IInspectableVftbl;
public _get_PropertyAsByte get_Current;
public _get_PropertyAsBoolean get_HasCurrent;
public _MoveNext MoveNext;
public _GetMany GetMany;
}
public struct IIterableOfByte
{
public IInspectableVftbl IInspectableVftbl;
public _get_PropertyAsObject get_First;
}
public struct IVectorViewOfByte
{
public unsafe delegate int _GetAt([In] IntPtr thisPtr, [In] uint index, [Out] out byte result);
public unsafe delegate int _IndexOf([In] IntPtr thisPtr, [In] byte value, [Out] out uint index, [Out, MarshalAs(UnmanagedType.Bool)] out bool found);
public unsafe delegate int _GetMany([In] IntPtr thisPtr, [In] uint startingIndex, [In] uint capacity, [In] ref byte[] values, [Out] out uint actual);
public IInspectableVftbl IInspectableVftbl;
public _GetAt GetAt;
public _get_PropertyAsUInt32 get_Size;
public _IndexOf IndexOf;
public _GetMany GetMany;
}
#endif
public object _WinRT_Owner { get; set; }
}
public static class DelegateExtensions
@ -515,14 +458,14 @@ namespace WinRT
return obj;
}
public static ObjectReference<T> FromNativePtr(object module, IntPtr thisPtr)
public static ObjectReference<T> FromNative(object module, IntPtr thisPtr)
{
var obj = new ObjectReference<T>(module, thisPtr, true);
obj._vftblIUnknown.AddRef(obj.ThisPtr);
return obj;
}
public static ObjectReference<T> FromNativePtr(IntPtr thisPtr)
public static ObjectReference<T> FromNative(IntPtr thisPtr)
{
// Retrieve module handle from QueryInterface function address
IntPtr qi;
@ -532,10 +475,10 @@ namespace WinRT
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
return FromNativePtr(new DllModuleHandle(moduleHandle), thisPtr);
return FromNative(new DllModuleHandle(moduleHandle), thisPtr);
}
public static ObjectReference<T> FromNativePtrNoRef(IntPtr thisPtr)
public static ObjectReference<T> FromNativeNoRef(IntPtr thisPtr)
{
return new ObjectReference<T>(null, thisPtr, false);
}
@ -731,7 +674,7 @@ namespace WinRT
{
IntPtr instancePtr = IntPtr.Zero;
unsafe { Marshal.ThrowExceptionForHR(_IActivationFactory.Vftbl.ActivateInstance(_IActivationFactory.ThisPtr, out instancePtr)); }
return ObjectReference<Interop.IInspectableVftbl>.Attach(_IActivationFactory.Module, ref instancePtr).As<I>();
return ObjectReference<WinRT.IInspectable.Vftbl>.Attach(_IActivationFactory.Module, ref instancePtr).As<I>();
}
ObjectReference<I> _As<I>()
@ -1234,182 +1177,6 @@ namespace WinRT
}
}
#if false
public class VectorViewOfObject<T> : IReadOnlyList<T>
{
ObjectReference<Interop.IVectorViewOfObject> _obj;
Guid _iidIterable;
internal delegate T CreateT(ObjectReference<Interop.IInspectableVftbl> obj);
CreateT _createT;
T _CreateT(ref IntPtr instancePtr) => _createT(ObjectReference<Interop.IInspectableVftbl>.Attach(_obj.Module, ref instancePtr));
internal VectorViewOfObject(ObjectReference<Interop.IVectorViewOfObject> obj, Guid iidIterable, CreateT createT)
{
_obj = obj;
_iidIterable = iidIterable;
_createT = createT;
}
public class Iterator : IEnumerator<T>
{
ObjectReference<Interop.IIteratorOfObject> _obj;
VectorViewOfObject<T> _parent;
internal Iterator(VectorViewOfObject<T> parent)
{
_parent = parent;
Reset();
}
public unsafe T Current
{
get
{
IntPtr instancePtr;
Marshal.ThrowExceptionForHR(_obj.Vftbl.get_Current(_obj.ThisPtr, out instancePtr));
return _parent._CreateT(ref instancePtr);
}
}
object IEnumerator.Current => Current;
public void Dispose()
{
_obj = null;
}
public unsafe bool MoveNext()
{
bool hasCurrent;
Marshal.ThrowExceptionForHR(_obj.Vftbl.MoveNext(_obj.ThisPtr, out hasCurrent));
return hasCurrent;
}
public unsafe void Reset()
{
var iterable = _parent._obj.As<Interop.IIterableOfObject>(_parent._iidIterable);
IntPtr iteratorPtr;
Marshal.ThrowExceptionForHR(iterable.Vftbl.get_First(iterable.ThisPtr, out iteratorPtr));
_obj = ObjectReference<Interop.IIteratorOfObject>.Attach(_parent._obj.Module, ref iteratorPtr);
}
}
public unsafe int Count
{
get
{
uint value;
Marshal.ThrowExceptionForHR(_obj.Vftbl.get_Size(_obj.ThisPtr, out value));
return (int)value;
}
}
public unsafe T this[int index]
{
get
{
IntPtr instancePtr;
Marshal.ThrowExceptionForHR(_obj.Vftbl.GetAt(_obj.ThisPtr, (uint)index, out instancePtr));
return _CreateT(ref instancePtr);
}
}
public unsafe IEnumerator<T> GetEnumerator()
{
return new Iterator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class VectorViewOfByte : IReadOnlyList<byte>
{
ObjectReference<Interop.IVectorViewOfByte> _obj;
Guid _iidIterable;
internal VectorViewOfByte(ObjectReference<Interop.IVectorViewOfByte> obj, Guid iidIterable)
{
_obj = obj;
_iidIterable = iidIterable;
}
public class Iterator : IEnumerator<byte>
{
ObjectReference<Interop.IIteratorOfByte> _obj;
VectorViewOfByte _parent;
internal Iterator(VectorViewOfByte parent)
{
_parent = parent;
Reset();
}
public unsafe byte Current
{
get
{
byte value;
Marshal.ThrowExceptionForHR(_obj.Vftbl.get_Current(_obj.ThisPtr, out value));
return value;
}
}
object IEnumerator.Current => Current;
public void Dispose()
{
_obj = null;
}
public unsafe bool MoveNext()
{
bool hasCurrent;
Marshal.ThrowExceptionForHR(_obj.Vftbl.MoveNext(_obj.ThisPtr, out hasCurrent));
return hasCurrent;
}
public unsafe void Reset()
{
var iterable = _parent._obj.As<Interop.IIterableOfByte>(_parent._iidIterable);
IntPtr iteratorPtr;
Marshal.ThrowExceptionForHR(iterable.Vftbl.get_First(iterable.ThisPtr, out iteratorPtr));
_obj = ObjectReference<Interop.IIteratorOfByte>.Attach(_parent._obj.Module, ref iteratorPtr);
}
}
public unsafe int Count
{
get
{
uint value;
Marshal.ThrowExceptionForHR(_obj.Vftbl.get_Size(_obj.ThisPtr, out value));
return (int)value;
}
}
public unsafe byte this[int index]
{
get
{
byte value;
Marshal.ThrowExceptionForHR(_obj.Vftbl.GetAt(_obj.ThisPtr, (uint)index, out value));
return value;
}
}
public unsafe IEnumerator<byte> GetEnumerator()
{
return new Iterator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
#endif
public static class TypeExtensions
{
public static bool IsDelegate(this Type type)
@ -1491,8 +1258,7 @@ namespace WinRT
public static string GetSignature(Type type)
{
// todo: project IInspectable
if (type == typeof(ObjectReference<Interop.IInspectableVftbl>))
if (type == typeof(IInspectable))
{
return "cinterface(IInspectable)";
}

Просмотреть файл

@ -24,6 +24,25 @@ namespace cswinrt
{
}
void write_begin()
{
write(R"(// This file was generated by cswinrt.exe
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using WinRT;
namespace %
{
)", _current_namespace);
}
void write_end()
{
write("}\n");
}
using indented_writer_base<writer>::write;
struct generic_params