Skip to content

Commit

Permalink
[.NET/CoreMidi] Use [UnmanagedCallersOnly] instead of [MonoPInvokeCal…
Browse files Browse the repository at this point in the history
…lback] Partial Fix for #10470 (#15774)

Ref: #10470.
  • Loading branch information
stephen-hawley committed Aug 26, 2022
1 parent 46907cb commit 9a40048
Showing 1 changed file with 85 additions and 8 deletions.
93 changes: 85 additions & 8 deletions src/CoreMidi/MidiServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,11 @@ internal MidiException (MidiError code) : base (code == MidiError.NotPermitted ?
public class MidiClient : MidiObject {
#if !COREBUILD
[DllImport (Constants.CoreMidiLibrary)]
#if NET
unsafe extern static int /* OSStatus = SInt32 */ MIDIClientCreate (IntPtr str, delegate* unmanaged<IntPtr, IntPtr, void> callback, IntPtr context, out MidiObjectRef handle);
#else
extern static int /* OSStatus = SInt32 */ MIDIClientCreate (IntPtr str, MidiNotifyProc callback, IntPtr context, out MidiObjectRef handle);
#endif

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIClientDispose (MidiObjectRef handle);
Expand Down Expand Up @@ -552,7 +556,14 @@ public MidiClient (string name)
{
using (var nsstr = new NSString (name)){
gch = GCHandle.Alloc (this);
int code = MIDIClientCreate (nsstr.Handle, ClientCallback, GCHandle.ToIntPtr (gch), out handle);
#if NET
int code = 0;
unsafe {
code = MIDIClientCreate (nsstr.Handle, &ClientCallback, GCHandle.ToIntPtr (gch), out handle);
}
#else
int code = MIDIClientCreate (nsstr.Handle, static_MidiNotifyProc, GCHandle.ToIntPtr (gch), out handle);
#endif
if (code != 0){
gch.Free ();
handle = MidiObject.InvalidRef;
Expand Down Expand Up @@ -639,10 +650,23 @@ public MidiPort CreateOutputPort (string name)
public event EventHandler? ThruConnectionsChanged;
public event EventHandler? SerialPortOwnerChanged;
public event EventHandler<IOErrorEventArgs>? IOError;

#if !NET
static MidiNotifyProc? _static_MidiNotifyProc;
static MidiNotifyProc static_MidiNotifyProc {
get {
if (_static_MidiNotifyProc is null)
_static_MidiNotifyProc = new MidiNotifyProc (ClientCallback);
return _static_MidiNotifyProc;
}
}
#endif
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (MidiNotifyProc))]
#endif
#endif // if NET
static void ClientCallback (IntPtr message, IntPtr context)
{
GCHandle gch = GCHandle.FromIntPtr (context);
Expand Down Expand Up @@ -954,9 +978,13 @@ public class MidiPort : MidiObject {
[Deprecated (PlatformName.iOS, 14,0)]
[Deprecated (PlatformName.MacOSX, 11,0)]
#endif
#if NET
[DllImport (Constants.CoreMidiLibrary)]
extern unsafe static int /* OSStatus = SInt32 */ MIDIInputPortCreate (MidiClientRef client, IntPtr /* CFStringRef */ portName, delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> readProc, IntPtr context, MidiPortRef* midiPort);
#else
[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIInputPortCreate (MidiClientRef client, IntPtr /* CFStringRef */ portName, MidiReadProc readProc, IntPtr context, out MidiPortRef midiPort);

#endif
[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIOutputPortCreate (MidiClientRef client, IntPtr /* CFStringRef */ portName, out MidiPortRef midiPort);

Expand All @@ -972,10 +1000,19 @@ internal MidiPort (MidiClient client, string portName, bool input)
GCHandle gch = GCHandle.Alloc (this);
int code;

if (input)
code = MIDIInputPortCreate (client.handle, nsstr.Handle, Read, GCHandle.ToIntPtr (gch), out handle);
else
if (input) {
#if NET
unsafe {
MidiPortRef tempHandle;
code = MIDIInputPortCreate (client.handle, nsstr.Handle, &Read, GCHandle.ToIntPtr (gch), &tempHandle);
handle = tempHandle;
}
#else
code = MIDIInputPortCreate (client.handle, nsstr.Handle, static_MidiReadProc, GCHandle.ToIntPtr (gch), out handle);
#endif
} else {
code = MIDIOutputPortCreate (client.handle, nsstr.Handle, out handle);
}

if (code != 0){
gch.Free ();
Expand Down Expand Up @@ -1010,9 +1047,23 @@ protected override void Dispose (bool disposing)

public event EventHandler<MidiPacketsEventArgs>? MessageReceived;

#if !NET
static MidiReadProc? _static_MidiReadProc;
static MidiReadProc static_MidiReadProc {
get {
if (_static_MidiReadProc is null)
_static_MidiReadProc = new MidiReadProc (Read);
return _static_MidiReadProc;
}
}
#endif
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (MidiReadProc))]
#endif
#endif // if NET
static void Read (IntPtr packetList, IntPtr context, IntPtr srcPtr)
{
GCHandle gch = GCHandle.FromIntPtr (context);
Expand Down Expand Up @@ -2117,8 +2168,13 @@ public class MidiEndpoint : MidiObject {
[Deprecated (PlatformName.iOS, 14,0)]
[Deprecated (PlatformName.MacOSX, 11,0)]
#endif
#if NET
[DllImport (Constants.CoreMidiLibrary)]
extern unsafe static MidiError /* OSStatus = SInt32 */ MIDIDestinationCreate (MidiClientRef client, IntPtr /* CFStringRef */ name, delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> readProc, IntPtr context, MidiEndpointRef* midiEndpoint);
#else
[DllImport (Constants.CoreMidiLibrary)]
extern static MidiError /* OSStatus = SInt32 */ MIDIDestinationCreate (MidiClientRef client, IntPtr /* CFStringRef */ name, MidiReadProc readProc, IntPtr context, out MidiEndpointRef midiEndpoint);
#endif

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIFlushOutput (MidiEndpointRef handle);
Expand Down Expand Up @@ -2195,8 +2251,15 @@ internal MidiEndpoint (MidiClient client, string name, out MidiError code)
{
using (var nsstr = new NSString (name)){
GCHandle gch = GCHandle.Alloc (this);

code = MIDIDestinationCreate (client.handle, nsstr.Handle, Read, GCHandle.ToIntPtr (gch), out handle);
#if NET
unsafe {
MidiEndpointRef tempHandle;
code = MIDIDestinationCreate (client.handle, nsstr.Handle, &Read, GCHandle.ToIntPtr (gch), &tempHandle);
handle = tempHandle;
}
#else
code = MIDIDestinationCreate (client.handle, nsstr.Handle, static_MidiReadProc, GCHandle.ToIntPtr (gch), out handle);
#endif
EndpointName = name;
}
}
Expand All @@ -2208,10 +2271,24 @@ protected override void Dispose (bool disposing)
}

public event EventHandler<MidiPacketsEventArgs>? MessageReceived;
#if !NET
static MidiReadProc? _static_MidiReadProc;
static MidiReadProc static_MidiReadProc {
get {
if (_static_MidiReadProc is null)
_static_MidiReadProc = new MidiReadProc (Read);
return _static_MidiReadProc;
}
}
#endif

#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (MidiReadProc))]
#endif
#endif // if NET
static void Read (IntPtr packetList, IntPtr context, IntPtr srcPtr)
{
GCHandle gch = GCHandle.FromIntPtr (context);
Expand Down

6 comments on commit 9a40048

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Status for 'xamarin-macios - sample testing (build)': failure.

  • ❌ Debug_iPhone_AF: Failed
  • ❌ Debug_iPhone_GR: Failed
  • ❌ Debug_iPhone_SZ: Failed
  • ❌ Debug_iPhoneSimulator: Failed
  • ❌ Release_iPhone_AF: Failed
  • ❌ Release_iPhone_GR: Failed
  • ❌ Release_iPhone_SZ: Failed
  • ❌ Release_iPhoneSimulator: Failed
  • ❌ Debug_Mac: Failed
  • ❌ Release_Mac: Failed
  • ❌ PublishPerformanceData: Failed

Please sign in to comment.