From 8bb2048f5f641ff7647383fe593cc44daade5184 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 30 Apr 2024 08:56:20 +0200 Subject: [PATCH] [GameController] Make P/Invokes have blittable signatures. (#20528) Contributes towards #15684. --- .../GCExtendedGamepadSnapshot.cs | 45 ++++++++++++------- src/GameController/GCGamepadSnapshot.cs | 23 ++++++---- src/GameController/GCMicroGamepadSnapshot.cs | 41 +++++++++++------ .../BlittablePInvokes.KnownFailures.cs | 10 ----- 4 files changed, 71 insertions(+), 48 deletions(-) diff --git a/src/GameController/GCExtendedGamepadSnapshot.cs b/src/GameController/GCExtendedGamepadSnapshot.cs index 6cbc345aa31e..7f8dc2d622e2 100644 --- a/src/GameController/GCExtendedGamepadSnapshot.cs +++ b/src/GameController/GCExtendedGamepadSnapshot.cs @@ -11,6 +11,7 @@ #nullable enable using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ObjCRuntime; @@ -85,13 +86,17 @@ public struct GCExtendedGamepadSnapShotDataV100 { [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] #endif [DllImport (Constants.GameControllerLibrary)] - static extern /* NSData * __nullable */ IntPtr NSDataFromGCExtendedGamepadSnapShotDataV100 ( - /* GCExtendedGamepadSnapShotDataV100 * __nullable */ ref GCExtendedGamepadSnapShotDataV100 snapshotData); + unsafe static extern /* NSData * __nullable */ IntPtr NSDataFromGCExtendedGamepadSnapShotDataV100 ( + /* GCExtendedGamepadSnapShotDataV100 * __nullable */ GCExtendedGamepadSnapShotDataV100* snapshotData); public NSData? ToNSData () { - var p = NSDataFromGCExtendedGamepadSnapShotDataV100 (ref this); - return p == IntPtr.Zero ? null : new NSData (p); + unsafe { + fixed (GCExtendedGamepadSnapShotDataV100* self = &this) { + var p = NSDataFromGCExtendedGamepadSnapShotDataV100 (self); + return p == IntPtr.Zero ? null : new NSData (p); + } + } } } @@ -202,8 +207,8 @@ public struct GCExtendedGamepadSnapshotData { [iOS (12, 2)] #endif [DllImport (Constants.GameControllerLibrary)] - static extern /* NSData * __nullable */ IntPtr NSDataFromGCExtendedGamepadSnapshotData ( - /* GCExtendedGamepadSnapshotData * __nullable */ ref GCExtendedGamepadSnapshotData snapshotData); + unsafe static extern /* NSData * __nullable */ IntPtr NSDataFromGCExtendedGamepadSnapshotData ( + /* GCExtendedGamepadSnapshotData * __nullable */ GCExtendedGamepadSnapshotData* snapshotData); #if NET [SupportedOSPlatform ("tvos12.2")] @@ -220,8 +225,12 @@ public struct GCExtendedGamepadSnapshotData { #endif public NSData? ToNSData () { - var p = NSDataFromGCExtendedGamepadSnapshotData (ref this); - return p == IntPtr.Zero ? null : new NSData (p); + unsafe { + fixed (GCExtendedGamepadSnapshotData* self = &this) { + var p = NSDataFromGCExtendedGamepadSnapshotData (self); + return p == IntPtr.Zero ? null : new NSData (p); + } + } } } @@ -229,9 +238,8 @@ public partial class GCExtendedGamepadSnapshot { // GCExtendedGamepadSnapshot.h [DllImport (Constants.GameControllerLibrary)] - [return: MarshalAs (UnmanagedType.I1)] - static extern bool GCExtendedGamepadSnapShotDataV100FromNSData ( - /* GCExtendedGamepadSnapShotDataV100 * __nullable */ out GCExtendedGamepadSnapShotDataV100 snapshotData, + unsafe static extern byte GCExtendedGamepadSnapShotDataV100FromNSData ( + /* GCExtendedGamepadSnapShotDataV100 * __nullable */ GCExtendedGamepadSnapShotDataV100* snapshotData, /* NSData * __nullable */ IntPtr data); #if NET @@ -248,14 +256,16 @@ public partial class GCExtendedGamepadSnapshot { [iOS (12, 2)] #endif [DllImport (Constants.GameControllerLibrary)] - [return: MarshalAs (UnmanagedType.I1)] - static extern bool GCExtendedGamepadSnapshotDataFromNSData ( - /* GCExtendedGamepadSnapshotData * __nullable */ out GCExtendedGamepadSnapshotData snapshotData, + unsafe static extern byte GCExtendedGamepadSnapshotDataFromNSData ( + /* GCExtendedGamepadSnapshotData * __nullable */ GCExtendedGamepadSnapshotData* snapshotData, /* NSData * __nullable */ IntPtr data); public static bool TryGetSnapShotData (NSData? data, out GCExtendedGamepadSnapShotDataV100 snapshotData) { - return GCExtendedGamepadSnapShotDataV100FromNSData (out snapshotData, data.GetHandle ()); + snapshotData = default; + unsafe { + return GCExtendedGamepadSnapShotDataV100FromNSData ((GCExtendedGamepadSnapShotDataV100*) Unsafe.AsPointer (ref snapshotData), data.GetHandle ()) != 0; + } } #if NET @@ -273,7 +283,10 @@ public static bool TryGetSnapShotData (NSData? data, out GCExtendedGamepadSnapSh #endif public static bool TryGetExtendedSnapShotData (NSData? data, out GCExtendedGamepadSnapshotData snapshotData) { - return GCExtendedGamepadSnapshotDataFromNSData (out snapshotData, data.GetHandle ()); + snapshotData = default; + unsafe { + return GCExtendedGamepadSnapshotDataFromNSData ((GCExtendedGamepadSnapshotData*) Unsafe.AsPointer (ref snapshotData), data.GetHandle ()) != 0; + } } } } diff --git a/src/GameController/GCGamepadSnapshot.cs b/src/GameController/GCGamepadSnapshot.cs index 69c71628776b..c09ee054a245 100644 --- a/src/GameController/GCGamepadSnapshot.cs +++ b/src/GameController/GCGamepadSnapshot.cs @@ -9,6 +9,7 @@ #nullable enable using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ObjCRuntime; @@ -51,13 +52,17 @@ public struct GCGamepadSnapShotDataV100 { public float /* float_t = float */ RightShoulder; [DllImport (Constants.GameControllerLibrary)] - static extern /* NSData * __nullable */ IntPtr NSDataFromGCGamepadSnapShotDataV100 ( - /* GCGamepadSnapShotDataV100 * __nullable */ ref GCGamepadSnapShotDataV100 snapshotData); + unsafe static extern /* NSData * __nullable */ IntPtr NSDataFromGCGamepadSnapShotDataV100 ( + /* GCGamepadSnapShotDataV100 * __nullable */ GCGamepadSnapShotDataV100* snapshotData); public NSData? ToNSData () { - var p = NSDataFromGCGamepadSnapShotDataV100 (ref this); - return p == IntPtr.Zero ? null : new NSData (p); + unsafe { + fixed (GCGamepadSnapShotDataV100* self = &this) { + var p = NSDataFromGCGamepadSnapShotDataV100 (self); + return p == IntPtr.Zero ? null : new NSData (p); + } + } } } @@ -65,14 +70,16 @@ public partial class GCGamepadSnapshot { // GCGamepadSnapshot.h [DllImport (Constants.GameControllerLibrary)] - [return: MarshalAs (UnmanagedType.I1)] - static extern bool GCGamepadSnapShotDataV100FromNSData ( - /* GCGamepadSnapShotDataV100 * __nullable */ out GCGamepadSnapShotDataV100 snapshotData, + unsafe static extern byte GCGamepadSnapShotDataV100FromNSData ( + /* GCGamepadSnapShotDataV100 * __nullable */ GCGamepadSnapShotDataV100* snapshotData, /* NSData * __nullable */ IntPtr data); public static bool TryGetSnapshotData (NSData? data, out GCGamepadSnapShotDataV100 snapshotData) { - return GCGamepadSnapShotDataV100FromNSData (out snapshotData, data.GetHandle ()); + snapshotData = default; + unsafe { + return GCGamepadSnapShotDataV100FromNSData ((GCGamepadSnapShotDataV100*) Unsafe.AsPointer (ref snapshotData), data.GetHandle ()) != 0; + } } } } diff --git a/src/GameController/GCMicroGamepadSnapshot.cs b/src/GameController/GCMicroGamepadSnapshot.cs index 83ec69ad5025..af793d79cef7 100644 --- a/src/GameController/GCMicroGamepadSnapshot.cs +++ b/src/GameController/GCMicroGamepadSnapshot.cs @@ -5,6 +5,7 @@ #if !WATCHOS using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ObjCRuntime; @@ -57,13 +58,17 @@ public struct GCMicroGamepadSnapShotDataV100 { [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCController.GetMicroGamepadController()' instead.")] #endif [DllImport (Constants.GameControllerLibrary)] - static extern /* NSData * __nullable */ IntPtr NSDataFromGCMicroGamepadSnapShotDataV100 ( - /* __nullable */ ref GCMicroGamepadSnapShotDataV100 snapshotData); + unsafe static extern /* NSData * __nullable */ IntPtr NSDataFromGCMicroGamepadSnapShotDataV100 ( + /* __nullable */ GCMicroGamepadSnapShotDataV100* snapshotData); public NSData? ToNSData () { - var p = NSDataFromGCMicroGamepadSnapShotDataV100 (ref this); - return p == IntPtr.Zero ? null : new NSData (p); + unsafe { + fixed (GCMicroGamepadSnapShotDataV100* self = &this) { + var p = NSDataFromGCMicroGamepadSnapShotDataV100 (self); + return p == IntPtr.Zero ? null : new NSData (p); + } + } } } @@ -111,8 +116,8 @@ public struct GCMicroGamepadSnapshotData { [iOS (12, 2)] #endif [DllImport (Constants.GameControllerLibrary)] - static extern /* NSData * __nullable */ IntPtr NSDataFromGCMicroGamepadSnapshotData ( - /* __nullable */ ref GCMicroGamepadSnapshotData snapshotData); + unsafe static extern /* NSData * __nullable */ IntPtr NSDataFromGCMicroGamepadSnapshotData ( + /* __nullable */ GCMicroGamepadSnapshotData* snapshotData); #if NET [SupportedOSPlatform ("tvos12.2")] @@ -128,8 +133,12 @@ public struct GCMicroGamepadSnapshotData { #endif public NSData? ToNSData () { - var p = NSDataFromGCMicroGamepadSnapshotData (ref this); - return p == IntPtr.Zero ? null : new NSData (p); + unsafe { + fixed (GCMicroGamepadSnapshotData* self = &this) { + var p = NSDataFromGCMicroGamepadSnapshotData (self); + return p == IntPtr.Zero ? null : new NSData (p); + } + } } } @@ -150,8 +159,7 @@ public partial class GCMicroGamepadSnapshot { [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCController.GetMicroGamepadController()' instead.")] #endif [DllImport (Constants.GameControllerLibrary)] - [return: MarshalAs (UnmanagedType.I1)] - static extern bool GCMicroGamepadSnapShotDataV100FromNSData (out GCMicroGamepadSnapShotDataV100 snapshotData, /* NSData */ IntPtr data); + unsafe static extern byte GCMicroGamepadSnapShotDataV100FromNSData (GCMicroGamepadSnapShotDataV100* snapshotData, /* NSData */ IntPtr data); #if NET [SupportedOSPlatform ("macos")] @@ -168,7 +176,10 @@ public partial class GCMicroGamepadSnapshot { #endif public static bool TryGetSnapshotData (NSData? data, out GCMicroGamepadSnapShotDataV100 snapshotData) { - return GCMicroGamepadSnapShotDataV100FromNSData (out snapshotData, data.GetHandle ()); + snapshotData = default; + unsafe { + return GCMicroGamepadSnapShotDataV100FromNSData ((GCMicroGamepadSnapShotDataV100*) Unsafe.AsPointer (ref snapshotData), data.GetHandle ()) != 0; + } } #if NET @@ -187,8 +198,7 @@ public static bool TryGetSnapshotData (NSData? data, out GCMicroGamepadSnapShotD [iOS (12, 2)] #endif [DllImport (Constants.GameControllerLibrary)] - [return: MarshalAs (UnmanagedType.I1)] - static extern bool GCMicroGamepadSnapshotDataFromNSData (out GCMicroGamepadSnapshotData snapshotData, /* NSData */ IntPtr data); + unsafe static extern byte GCMicroGamepadSnapshotDataFromNSData (GCMicroGamepadSnapshotData* snapshotData, /* NSData */ IntPtr data); #if NET [SupportedOSPlatform ("tvos12.2")] @@ -204,7 +214,10 @@ public static bool TryGetSnapshotData (NSData? data, out GCMicroGamepadSnapShotD #endif public static bool TryGetSnapshotData (NSData? data, out GCMicroGamepadSnapshotData snapshotData) { - return GCMicroGamepadSnapshotDataFromNSData (out snapshotData, data.GetHandle ()); + snapshotData = default; + unsafe { + return GCMicroGamepadSnapshotDataFromNSData ((GCMicroGamepadSnapshotData*) Unsafe.AsPointer (ref snapshotData), data.GetHandle ()) != 0; + } } } diff --git a/tests/cecil-tests/BlittablePInvokes.KnownFailures.cs b/tests/cecil-tests/BlittablePInvokes.KnownFailures.cs index 54890a39ad18..7a4dd5937c16 100644 --- a/tests/cecil-tests/BlittablePInvokes.KnownFailures.cs +++ b/tests/cecil-tests/BlittablePInvokes.KnownFailures.cs @@ -143,11 +143,6 @@ public partial class BlittablePInvokes { "Security.SslStatus Security.SslContext::SSLSetSessionOption(System.IntPtr,Security.SslSessionOption,System.Boolean)", "Security.SslStatus Security.SslContext::SSLWrite(System.IntPtr,System.Byte*,System.IntPtr,System.IntPtr&)", "System.Boolean Foundation.NSObject::xamarin_set_gchandle_with_flags_safe(System.IntPtr,System.IntPtr,Foundation.NSObject/XamarinGCHandleFlags)", - "System.Boolean GameController.GCExtendedGamepadSnapshot::GCExtendedGamepadSnapshotDataFromNSData(GameController.GCExtendedGamepadSnapshotData&,System.IntPtr)", - "System.Boolean GameController.GCExtendedGamepadSnapshot::GCExtendedGamepadSnapShotDataV100FromNSData(GameController.GCExtendedGamepadSnapShotDataV100&,System.IntPtr)", - "System.Boolean GameController.GCGamepadSnapshot::GCGamepadSnapShotDataV100FromNSData(GameController.GCGamepadSnapShotDataV100&,System.IntPtr)", - "System.Boolean GameController.GCMicroGamepadSnapshot::GCMicroGamepadSnapshotDataFromNSData(GameController.GCMicroGamepadSnapshotData&,System.IntPtr)", - "System.Boolean GameController.GCMicroGamepadSnapshot::GCMicroGamepadSnapShotDataV100FromNSData(GameController.GCMicroGamepadSnapShotDataV100&,System.IntPtr)", "System.Boolean Network.NWAdvertiseDescriptor::nw_advertise_descriptor_get_no_auto_rename(System.IntPtr)", "System.Boolean Network.NWBrowserDescriptor::nw_browse_descriptor_get_include_txt_record(System.IntPtr)", "System.Boolean Network.NWConnectionGroup::nw_connection_group_reinsert_extracted_connection(System.IntPtr,System.IntPtr)", @@ -226,11 +221,6 @@ public partial class BlittablePInvokes { "System.Int32 Security.SslContext::SSLSetSessionTicketsEnabled(System.IntPtr,System.Boolean)", "System.IntPtr Foundation.NSSearchPath::NSSearchPathForDirectoriesInDomains(System.UIntPtr,System.UIntPtr,System.Boolean)", "System.IntPtr Foundation.NSThread::xamarin_init_nsthread(System.IntPtr,System.Boolean,System.IntPtr,System.IntPtr,System.IntPtr)", - "System.IntPtr GameController.GCExtendedGamepadSnapshotData::NSDataFromGCExtendedGamepadSnapshotData(GameController.GCExtendedGamepadSnapshotData&)", - "System.IntPtr GameController.GCExtendedGamepadSnapShotDataV100::NSDataFromGCExtendedGamepadSnapShotDataV100(GameController.GCExtendedGamepadSnapShotDataV100&)", - "System.IntPtr GameController.GCGamepadSnapShotDataV100::NSDataFromGCGamepadSnapShotDataV100(GameController.GCGamepadSnapShotDataV100&)", - "System.IntPtr GameController.GCMicroGamepadSnapshotData::NSDataFromGCMicroGamepadSnapshotData(GameController.GCMicroGamepadSnapshotData&)", - "System.IntPtr GameController.GCMicroGamepadSnapShotDataV100::NSDataFromGCMicroGamepadSnapShotDataV100(GameController.GCMicroGamepadSnapShotDataV100&)", "System.IntPtr ObjCRuntime.Selector::GetHandle(System.String)", "System.IntPtr Security.SecAccessControl::SecAccessControlCreateWithFlags(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr&)", "System.IntPtr Security.SecCertificate::SecCertificateCopySerialNumberData(System.IntPtr,System.IntPtr&)",