Skip to content

Commit 1a37329

Browse files
Copilotjtschuster
andcommitted
Simplify UniqueMarshalling native export using StrategyBasedComWrappers
Removed custom MyComWrapper implementation and ImplementingObject class. Now using StrategyBasedComWrappers directly with SharedTypes.ComInterfaces.UniqueMarshalling instance, which leverages the GeneratedComClass attribute to handle the COM vtable automatically. Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com>
1 parent 3d67609 commit 1a37329

File tree

1 file changed

+4
-113
lines changed
  • src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/ComInterfaceGenerator

1 file changed

+4
-113
lines changed
Lines changed: 4 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
5-
using System.Collections;
6-
using System.Runtime.CompilerServices;
74
using System.Runtime.InteropServices;
5+
using System.Runtime.InteropServices.Marshalling;
86
using SharedTypes.ComInterfaces;
9-
using static System.Runtime.InteropServices.ComWrappers;
107

118
namespace NativeExports.ComInterfaceGenerator
129
{
@@ -16,117 +13,11 @@ public static unsafe class UniqueMarshalling
1613
[UnmanagedCallersOnly(EntryPoint = "new_unique_marshalling")]
1714
public static void* CreateComObject()
1815
{
19-
MyComWrapper cw = new();
20-
var myObject = new ImplementingObject();
21-
nint ptr = cw.GetOrCreateComInterfaceForObject(myObject, CreateComInterfaceFlags.None);
16+
StrategyBasedComWrappers wrappers = new();
17+
var myObject = new SharedTypes.ComInterfaces.UniqueMarshalling();
18+
nint ptr = wrappers.GetOrCreateComInterfaceForObject(myObject, CreateComInterfaceFlags.None);
2219

2320
return (void*)ptr;
2421
}
25-
26-
class MyComWrapper : ComWrappers
27-
{
28-
static void* _s_comInterface1VTable = null;
29-
static void* s_comInterface1VTable
30-
{
31-
get
32-
{
33-
if (MyComWrapper._s_comInterface1VTable != null)
34-
return _s_comInterface1VTable;
35-
void** vtable = (void**)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(UniqueMarshalling), sizeof(void*) * 6);
36-
GetIUnknownImpl(out var fpQueryInterface, out var fpAddReference, out var fpRelease);
37-
vtable[0] = (void*)fpQueryInterface;
38-
vtable[1] = (void*)fpAddReference;
39-
vtable[2] = (void*)fpRelease;
40-
vtable[3] = (delegate* unmanaged<void*, int*, int>)&ImplementingObject.ABI.GetValue;
41-
vtable[4] = (delegate* unmanaged<void*, int, int>)&ImplementingObject.ABI.SetValue;
42-
vtable[5] = (delegate* unmanaged<void*, void**, int>)&ImplementingObject.ABI.GetThis;
43-
_s_comInterface1VTable = vtable;
44-
return _s_comInterface1VTable;
45-
}
46-
}
47-
protected override ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
48-
{
49-
if (obj is ImplementingObject)
50-
{
51-
ComInterfaceEntry* comInterfaceEntry = (ComInterfaceEntry*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ImplementingObject), sizeof(ComInterfaceEntry));
52-
comInterfaceEntry->IID = new Guid(IUniqueMarshalling.IID);
53-
comInterfaceEntry->Vtable = (nint)s_comInterface1VTable;
54-
count = 1;
55-
return comInterfaceEntry;
56-
}
57-
count = 0;
58-
return null;
59-
}
60-
61-
protected override object? CreateObject(nint externalComObject, CreateObjectFlags flags) => throw new NotImplementedException();
62-
protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException();
63-
}
64-
65-
class ImplementingObject : IUniqueMarshalling
66-
{
67-
int _data = 0;
68-
69-
int IUniqueMarshalling.GetValue()
70-
{
71-
return _data;
72-
}
73-
void IUniqueMarshalling.SetValue(int x)
74-
{
75-
_data = x;
76-
}
77-
IUniqueMarshalling IUniqueMarshalling.GetThis()
78-
{
79-
return this;
80-
}
81-
82-
// Provides function pointers in the COM format to use in COM VTables
83-
public static class ABI
84-
{
85-
86-
[UnmanagedCallersOnly]
87-
public static int GetValue(void* @this, int* value)
88-
{
89-
try
90-
{
91-
*value = ComInterfaceDispatch.GetInstance<IUniqueMarshalling>((ComInterfaceDispatch*)@this).GetValue();
92-
return 0;
93-
}
94-
catch (Exception e)
95-
{
96-
return e.HResult;
97-
}
98-
}
99-
100-
[UnmanagedCallersOnly]
101-
public static int SetValue(void* @this, int newValue)
102-
{
103-
try
104-
{
105-
ComInterfaceDispatch.GetInstance<IUniqueMarshalling>((ComInterfaceDispatch*)@this).SetValue(newValue);
106-
return 0;
107-
}
108-
catch (Exception e)
109-
{
110-
return e.HResult;
111-
}
112-
}
113-
114-
[UnmanagedCallersOnly]
115-
public static int GetThis(void* @this, void** value)
116-
{
117-
try
118-
{
119-
IUniqueMarshalling result = ComInterfaceDispatch.GetInstance<IUniqueMarshalling>((ComInterfaceDispatch*)@this).GetThis();
120-
MyComWrapper cw = new();
121-
*value = (void*)cw.GetOrCreateComInterfaceForObject(result, CreateComInterfaceFlags.None);
122-
return 0;
123-
}
124-
catch (Exception e)
125-
{
126-
return e.HResult;
127-
}
128-
}
129-
}
130-
}
13122
}
13223
}

0 commit comments

Comments
 (0)