diff --git a/DllImportGenerator/Ancillary.Interop/MarshalEx.cs b/DllImportGenerator/Ancillary.Interop/MarshalEx.cs
index a5ad55f72e68..8a53af07090d 100644
--- a/DllImportGenerator/Ancillary.Interop/MarshalEx.cs
+++ b/DllImportGenerator/Ancillary.Interop/MarshalEx.cs
@@ -10,32 +10,12 @@ namespace System.Runtime.InteropServices
///
public static class MarshalEx
{
- ///
- /// Create an instance of the given .
- ///
- /// Type of the SafeHandle
- /// New instance of
- ///
- /// The must be non-abstract and have a parameterless constructor.
- ///
- 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)
- {
- throw new MissingMemberException($"The safe handle type '{typeof(TSafeHandle).FullName}' must be a non-abstract type with a parameterless constructor.");
- }
-
- TSafeHandle safeHandle = (TSafeHandle)Activator.CreateInstance(typeof(TSafeHandle), nonPublic: true)!;
- return safeHandle;
- }
-
///
/// Sets the handle of to the specified .
///
/// instance to update
/// Pre-existing handle
- public static void SetHandle(SafeHandle safeHandle, IntPtr handle)
+ public static void InitHandle(SafeHandle safeHandle, IntPtr handle)
{
typeof(SafeHandle).GetMethod("SetHandle", BindingFlags.NonPublic | BindingFlags.Instance)!.Invoke(safeHandle, new object[] { handle });
}
diff --git a/DllImportGenerator/DllImportGenerator.IntegrationTests/SafeHandleTests.cs b/DllImportGenerator/DllImportGenerator.IntegrationTests/SafeHandleTests.cs
index 1a6b47a63bed..fda3852b3d88 100644
--- a/DllImportGenerator/DllImportGenerator.IntegrationTests/SafeHandleTests.cs
+++ b/DllImportGenerator/DllImportGenerator.IntegrationTests/SafeHandleTests.cs
@@ -7,7 +7,7 @@ namespace DllImportGenerator.IntegrationTests
{
partial class NativeExportsNE
{
- public class NativeExportsSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
+ public partial class NativeExportsSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private NativeExportsSafeHandle() : base(ownsHandle: true)
{ }
@@ -18,6 +18,12 @@ protected override bool ReleaseHandle()
Assert.True(didRelease);
return didRelease;
}
+
+ public static NativeExportsSafeHandle CreateNewHandle() => AllocateHandle();
+
+
+ [GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "alloc_handle")]
+ private static partial NativeExportsSafeHandle AllocateHandle();
}
[GeneratedDllImport(NativeExportsNE_Binary, EntryPoint = "alloc_handle")]
@@ -48,6 +54,14 @@ public void ReturnValue_CreatesSafeHandle()
Assert.False(handle.IsInvalid);
}
+ [Fact]
+ public void ReturnValue_CreatesSafeHandle_DirectConstructorCall()
+ {
+ using NativeExportsNE.NativeExportsSafeHandle handle = NativeExportsNE.NativeExportsSafeHandle.CreateNewHandle();
+ Assert.False(handle.IsClosed);
+ Assert.False(handle.IsInvalid);
+ }
+
[Fact]
public void ByValue_CorrectlyUnwrapsHandle()
{
diff --git a/DllImportGenerator/DllImportGenerator.UnitTests/CodeSnippets.cs b/DllImportGenerator/DllImportGenerator.UnitTests/CodeSnippets.cs
index 324b66ece135..f27cd8467185 100644
--- a/DllImportGenerator/DllImportGenerator.UnitTests/CodeSnippets.cs
+++ b/DllImportGenerator/DllImportGenerator.UnitTests/CodeSnippets.cs
@@ -919,5 +919,15 @@ public IntStructWrapperNative(IntStructWrapper managed)
public IntStructWrapper ToManaged() => new IntStructWrapper { Value = value };
}
";
+
+ public static string SafeHandleWithCustomDefaultConstructorAccessibility(bool privateCtor) => BasicParametersAndModifiers("MySafeHandle") + $@"
+class MySafeHandle : SafeHandle
+{{
+ {(privateCtor ? "private" : "public")} MySafeHandle() : base(System.IntPtr.Zero, true) {{ }}
+
+ public override bool IsInvalid => handle == System.IntPtr.Zero;
+
+ protected override bool ReleaseHandle() => true;
+}}";
}
}
diff --git a/DllImportGenerator/DllImportGenerator.UnitTests/Compiles.cs b/DllImportGenerator/DllImportGenerator.UnitTests/Compiles.cs
index 1db8e4b0ead8..004d2a01627f 100644
--- a/DllImportGenerator/DllImportGenerator.UnitTests/Compiles.cs
+++ b/DllImportGenerator/DllImportGenerator.UnitTests/Compiles.cs
@@ -124,6 +124,8 @@ public static IEnumerable