Skip to content

Commit

Permalink
[.NET/AudioToolbox] Make AudioServicesAddSystemSoundCompletion take a…
Browse files Browse the repository at this point in the history
…n unmanaged function pointer instead of delegate. Very partial fix for xamarin#10470.

In .NET 6 we can use the [UnmanagedCallersOnly] attribute to mark functions
that are called from native code (instead of the [MonoPInvokeCallback]
attribute). It turns out this is a rather major refactoring (in particular for
blocks), so start by doing it for just a single function, to make sure using
[UnmanagedCallersOnly] at least works somewhere.

Ref: xamarin#10470
  • Loading branch information
rolfbjarne committed Oct 4, 2021
1 parent 44f570e commit d335df0
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/AudioToolbox/SystemSound.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ public class SystemSound : INativeObject, IDisposable {

Action completionRoutine;
GCHandle gc_handle;

#if !NET
static readonly AddSystemSoundCompletionCallback SoundCompletionCallback = SoundCompletionShared;
#endif

internal SystemSound (uint soundId, bool ownsHandle)
{
Expand Down Expand Up @@ -310,12 +313,22 @@ public static SystemSound FromFile (string filename)
}
}

#if !NET
delegate void AddSystemSoundCompletionCallback (SystemSoundId id, IntPtr clientData);
#endif

[DllImport (Constants.AudioToolboxLibrary)]
#if NET
unsafe static extern AudioServicesError AudioServicesAddSystemSoundCompletion (uint soundId, IntPtr runLoop, IntPtr runLoopMode, delegate* unmanaged<SystemSoundId, IntPtr, void> completionRoutine, IntPtr clientData);
#else
static extern AudioServicesError AudioServicesAddSystemSoundCompletion (uint soundId, IntPtr runLoop, IntPtr runLoopMode, AddSystemSoundCompletionCallback completionRoutine, IntPtr clientData);
#endif

#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (Action<SystemSoundId, IntPtr>))]
#endif
static void SoundCompletionShared (SystemSoundId id, IntPtr clientData)
{
GCHandle gch = GCHandle.FromIntPtr (clientData);
Expand All @@ -332,10 +345,17 @@ public AudioServicesError AddSystemSoundCompletion (Action routine, CFRunLoop ru
gc_handle = GCHandle.Alloc (this);
completionRoutine = routine;

return AudioServicesAddSystemSoundCompletion (soundId,
unsafe {
return AudioServicesAddSystemSoundCompletion (soundId,
runLoop == null ? IntPtr.Zero : runLoop.Handle,
IntPtr.Zero, // runLoopMode should be enum runLoopMode == null ? IntPtr.Zero : runLoopMode.Handle,
SoundCompletionCallback, GCHandle.ToIntPtr (gc_handle));
#if NET
&SoundCompletionShared,
#else
SoundCompletionCallback,
#endif
GCHandle.ToIntPtr (gc_handle));
}
}

[DllImport (Constants.AudioToolboxLibrary)]
Expand Down

0 comments on commit d335df0

Please sign in to comment.