Skip to content

Commit 0bf77b2

Browse files
authored
Fix CA2256 in COM generator when using 'ManagedObjectWrapper' (#114642)
1 parent b0c2d75 commit 0bf77b2

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
185185
using StringWriter source = new();
186186
source.WriteLine("// <auto-generated />");
187187
source.WriteLine("#pragma warning disable CS0612, CS0618"); // Suppress warnings about [Obsolete] member usage in generated code.
188+
189+
// If the user has specified 'ManagedObjectWrapper', it means that the COM interface will never be used to marshal a native
190+
// object as an RCW (eg. the IDIC vtable will also not be generated, nor any additional supporting code). To reduce binary
191+
// size, we're not emitting the interface methods on the implementation interface that has '[DynamicInterfaceCastableImplementation]'
192+
// on it. However, doing so will cause the CA2256 warning to be produced. We can't remove the attribute, as that would cause
193+
// the wrong exception to be thrown when trying an IDIC cast with this interface (not 'InvalidCastException'). Because this is
194+
// a niche scenario, and we don't want to regress perf or size, we can just disable the warning instead.
195+
if (interfaceContext.Options is ComInterfaceOptions.ManagedObjectWrapper)
196+
{
197+
source.WriteLine("#pragma warning disable CA2256");
198+
}
199+
188200
interfaceInfo.WriteTo(source);
189201
// Two newlines looks cleaner than one
190202
source.WriteLine();

src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/ComInterfaceOptions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ public enum ComInterfaceOptions
2323
/// <summary>
2424
/// Generate a wrapper for managed objects to enable exposing them through the COM interface.
2525
/// </summary>
26+
/// <remarks>
27+
/// <para>
28+
/// When this flag is the only one specified on a given COM interface, no implementation methods will be generated
29+
/// to support <see cref="System.Runtime.InteropServices.IDynamicInterfaceCastable"/> casts. In such a scenario,
30+
/// attempting to cast to that interface type will still succeed, but any calls to interface methods will fail.
31+
/// </para>
32+
/// <para>
33+
/// Using only this flag is purely a binary size optimization. If calling methods via this interface on native
34+
/// object is required, the <see cref="ComObjectWrapper"/> flag should also be used instead.
35+
/// </para>
36+
/// </remarks>
2637
ManagedObjectWrapper = 0x1,
2738
/// <summary>
2839
/// Generate a wrapper for COM objects to enable exposing them through the managed interface.

0 commit comments

Comments
 (0)