Skip to content

Commit

Permalink
Generic CreateMarshaler (microsoft#1079)
Browse files Browse the repository at this point in the history
* Add generic CreateMarshaler
  • Loading branch information
j0shuams authored Jan 19, 2022
1 parent 3bf2eaa commit bfd6846
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 19 deletions.
13 changes: 9 additions & 4 deletions src/WinRT.Runtime/Marshalers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ private static Func<IObjectReference, IObjectReference> BindAs()
#endif
static class MarshalInspectable<T>
{
public static IObjectReference CreateMarshaler(T o, bool unwrapObject = true)
public static IObjectReference CreateMarshaler<V>(T o, Guid iid, bool unwrapObject = true)
{
if (o is null)
{
Expand All @@ -1149,20 +1149,25 @@ public static IObjectReference CreateMarshaler(T o, bool unwrapObject = true)

if (unwrapObject && ComWrappersSupport.TryUnwrapObject(o, out var objRef))
{
return objRef.As<IInspectable.Vftbl>(IInspectable.IID);
return objRef.As<V>(iid);
}
var publicType = o.GetType();
Type helperType = Projections.FindCustomHelperTypeMapping(publicType, true);
if (helperType != null)
{
var parms = new[] { Expression.Parameter(typeof(object), "arg") };
var createMarshaler = Expression.Lambda<Func<object, IObjectReference>>(
Expression.Call(helperType.GetMethod("CreateMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static),
Expression.Call(helperType.GetMethod("CreateMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static),
new[] { Expression.Convert(parms[0], publicType) }), parms).Compile();
return createMarshaler(o);
}

return ComWrappersSupport.CreateCCWForObject<IInspectable.Vftbl>(o, IInspectable.IID);
return ComWrappersSupport.CreateCCWForObject<V>(o, iid);
}

public static IObjectReference CreateMarshaler(T o, bool unwrapObject = true)
{
return CreateMarshaler<IInspectable.Vftbl>(o, IInspectable.IID, unwrapObject);
}

public static IntPtr GetAbi(IObjectReference objRef) =>
Expand Down
3 changes: 2 additions & 1 deletion src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ MembersMustExist : Member 'public void WinRT.MarshalString..ctor(System.String)'
MembersMustExist : Member 'public WinRT.MarshalString.Pinnable WinRT.MarshalString.CreatePinnable(System.String)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public System.IntPtr WinRT.MarshalString.GetAbi()' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public System.IntPtr WinRT.MarshalString.GetAbi(WinRT.MarshalString.Pinnable)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.IObjectReference WinRT.MarshalInspectable<T>.CreateMarshaler<V>(T, System.Guid, System.Boolean)' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.MarshalString.Pinnable' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.Interop.IWeakReference' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.Interop.IWeakReferenceSource' does not exist in the reference but it does exist in the implementation.
Total Issues: 19
Total Issues: 20
19 changes: 5 additions & 14 deletions src/cswinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -6470,23 +6470,14 @@ public static unsafe void DisposeAbiArray(object box) => MarshalInspectable<obje
});
if (is_exclusive_to_default)
{
auto is_generic = distance(type.GenericParam()) > 0;
auto default_interface_abi_name = get_default_interface_name(w, type, true);
w.write("public static IObjectReference CreateMarshaler(% obj) => obj is null ? null : MarshalInspectable<%>.CreateMarshaler(obj)%;",
w.write("public static IObjectReference CreateMarshaler(% obj) => obj is null ? null : MarshalInspectable<%>.CreateMarshaler<%>(obj, %);",
projected_type_name,
projected_type_name,
bind([&](writer& w)
{
if (distance(type.GenericParam()) > 0)
{
w.write(".As<%.Vftbl>()", default_interface_abi_name);
}
else
{
w.write(
".As<IUnknownVftbl>(GuidGenerator.GetIID(typeof(%).GetHelperType()))",
bind<write_type_name>(get_type_semantics(get_default_interface(type)), typedef_name_type::CCW, false));
}
}));
is_generic ? w.write_temp("%.Vftbl", default_interface_abi_name) : w.write_temp("IUnknownVftbl"),
is_generic ? w.write_temp("GuidGenerator.GetIID(%.Vftbl)", default_interface_abi_name)
: w.write_temp("GuidGenerator.GetIID(typeof(%).GetHelperType())", bind<write_type_name>(get_type_semantics(get_default_interface(type)), typedef_name_type::CCW, false)));
}
else
{
Expand Down

0 comments on commit bfd6846

Please sign in to comment.