Skip to content

Commit

Permalink
Add DynamicallyAccessedMembers attribute to CreateSafeHandle API (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
elinor-fung authored Nov 21, 2020
1 parent fee212a commit e4bdc07
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@

namespace System.Runtime.InteropServices
{
// [TODO] Remove once the attribute has been added to the BCL
/// <summary>
/// Indicates that method will be generated at compile time and invoke into an unmanaged library entry point
/// </summary>
/// <remarks>
/// IL linker/trimming currently has special handling of P/Invokes (pinvokeimpl):
/// - https://github.com/mono/linker/blob/bfab847356063d21eb15e79f2b6c03df5bd6ef3d/src/linker/Linker.Steps/MarkStep.cs#L2623
/// We may want to make the linker aware of this attribute as well.
/// </remarks>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class GeneratedDllImportAttribute : Attribute
{
Expand Down
16 changes: 15 additions & 1 deletion DllImportGenerator/Ancillary.Interop/MarshalEx.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

using System.Diagnostics.CodeAnalysis;
using System.Reflection;

namespace System.Runtime.InteropServices
Expand All @@ -9,7 +10,15 @@ namespace System.Runtime.InteropServices
/// </summary>
public static class MarshalEx
{
public static TSafeHandle CreateSafeHandle<TSafeHandle>()
/// <summary>
/// Create an instance of the given <typeparamref name="TSafeHandle"/>.
/// </summary>
/// <typeparam name="TSafeHandle">Type of the SafeHandle</typeparam>
/// <returns>New instance of <typeparamref name="TSafeHandle"/></returns>
/// <remarks>
/// The <typeparamref name="TSafeHandle"/> must be non-abstract and have a parameterless constructor.
/// </remarks>
public static TSafeHandle CreateSafeHandle<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors)]TSafeHandle>()
where TSafeHandle : SafeHandle
{
if (typeof(TSafeHandle).IsAbstract || typeof(TSafeHandle).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance, null, Type.EmptyTypes, null) == null)
Expand All @@ -21,6 +30,11 @@ public static TSafeHandle CreateSafeHandle<TSafeHandle>()
return safeHandle;
}

/// <summary>
/// Sets the handle of <paramref name="safeHandle"/> to the specified <paramref name="handle"/>.
/// </summary>
/// <param name="safeHandle"><see cref="SafeHandle"/> instance to update</param>
/// <param name="handle">Pre-existing handle</param>
public static void SetHandle(SafeHandle safeHandle, IntPtr handle)
{
typeof(SafeHandle).GetMethod("SetHandle", BindingFlags.NonPublic | BindingFlags.Instance)!.Invoke(safeHandle, new object[] { handle });
Expand Down

0 comments on commit e4bdc07

Please sign in to comment.