Skip to content

Commit

Permalink
Add free threaded marshaling to all managed objects (#836)
Browse files Browse the repository at this point in the history
* Add free threaded marshaler on all CCW if they don't already implement it.

* Add test for delegates
  • Loading branch information
manodasanW authored May 5, 2021
1 parent 3f5dd34 commit 396128c
Show file tree
Hide file tree
Showing 3 changed files with 362 additions and 3 deletions.
53 changes: 53 additions & 0 deletions src/Tests/UnitTest/TestComponentCSharp_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1313,8 +1313,61 @@ public void TestSimpleCCWs()
var managedProperties = new ManagedProperties(42);
TestObject.CopyProperties(managedProperties);
Assert.Equal(managedProperties.ReadWriteProperty, TestObject.ReadWriteProperty);
}

[Fact]
public void TestCCWMarshaler()
{
Guid IID_IMarshal = new Guid("00000003-0000-0000-c000-000000000046");
var managedProperties = new ManagedProperties(42);
IObjectReference ccw = MarshalInterface<IProperties1>.CreateMarshaler(managedProperties);
ccw.TryAs<IUnknownVftbl>(IID_IMarshal, out var marshalCCW);
Assert.NotNull(marshalCCW);

var array = new byte[] { 0x01 };
var buff = array.AsBuffer();
IObjectReference ccw2 = MarshalInterface<IBuffer>.CreateMarshaler(buff);
ccw2.TryAs<IUnknownVftbl>(IID_IMarshal, out var marshalCCW2);
Assert.NotNull(marshalCCW2);
}

#if !NETCOREAPP2_0
[Fact]
public void TestDelegateCCWMarshaler()
{
CreateAndValidateStreamedFile().Wait();
}

private async Task CreateAndValidateStreamedFile()
{
var storageFile = await StorageFile.CreateStreamedFileAsync("CreateAndValidateStreamedFile.txt", StreamedFileWriter, null);
using var inputStream = await storageFile.OpenSequentialReadAsync();
using var stream = inputStream.AsStreamForRead();
byte[] buff = new byte[50];
var numRead = stream.Read(buff, 0, 50);
Assert.True(numRead > 0);
var result = System.Text.Encoding.Default.GetString(buff, 0, numRead).TrimEnd(null);
Assert.Equal("Success!", result);
}

private static async void StreamedFileWriter(StreamedFileDataRequest request)
{
try
{
using (var stream = request.AsStreamForWrite())
using (var streamWriter = new StreamWriter(stream))
{
await streamWriter.WriteLineAsync("Success!");
}
request.Dispose();
}
catch (Exception)
{
request.FailAndClose(StreamedFileFailureMode.Incomplete);
}
}
#endif

[Fact]
public void TestWeakReference()
{
Expand Down
24 changes: 21 additions & 3 deletions src/WinRT.Runtime/ComWrappersSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,23 @@ internal static List<ComInterfaceEntry> GetInterfaceTableEntries(Type type)
var entries = new List<ComInterfaceEntry>();
var objType = type.GetRuntimeClassCCWType() ?? type;
var interfaces = objType.GetInterfaces();
bool hasCustomIMarshalInterface = false;
foreach (var iface in interfaces)
{
if (Projections.IsTypeWindowsRuntimeType(iface))
{
var ifaceAbiType = iface.FindHelperType();
Guid iid = GuidGenerator.GetIID(ifaceAbiType);
entries.Add(new ComInterfaceEntry
{
IID = GuidGenerator.GetIID(ifaceAbiType),
IID = iid,
Vtable = (IntPtr)ifaceAbiType.GetAbiToProjectionVftblPtr()
});

if(!hasCustomIMarshalInterface && iid == typeof(ABI.WinRT.Interop.IMarshal.Vftbl).GUID)
{
hasCustomIMarshalInterface = true;
}
}

if (iface.IsConstructedGenericType
Expand Down Expand Up @@ -171,14 +178,25 @@ internal static List<ComInterfaceEntry> GetInterfaceTableEntries(Type type)
{
IID = typeof(ABI.WinRT.Interop.IWeakReferenceSource.Vftbl).GUID,
Vtable = ABI.WinRT.Interop.IWeakReferenceSource.Vftbl.AbiToProjectionVftablePtr
});
});

// Add IMarhal implemented using the free threaded marshaler
// to all CCWs if it doesn't already have its own.
if (!hasCustomIMarshalInterface)
{
entries.Add(new ComInterfaceEntry
{
IID = typeof(ABI.WinRT.Interop.IMarshal.Vftbl).GUID,
Vtable = ABI.WinRT.Interop.IMarshal.Vftbl.AbiToProjectionVftablePtr
});
}

// Add IAgileObject to all CCWs
entries.Add(new ComInterfaceEntry
{
IID = typeof(ABI.WinRT.Interop.IAgileObject.Vftbl).GUID,
Vtable = IUnknownVftbl.AbiToProjectionVftblPtr
});
});
return entries;
}

Expand Down
Loading

0 comments on commit 396128c

Please sign in to comment.