Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CoreMidi] Make P/Invokes have blittable signatures. #19706

Merged
merged 1 commit into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 62 additions & 36 deletions src/CoreMidi/MidiServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,14 @@ internal MidiObject ()
}

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIObjectGetIntegerProperty (MidiObjectRef obj, IntPtr str, out int /* SInt32 */ ret);
unsafe extern static int /* OSStatus = SInt32 */ MIDIObjectGetIntegerProperty (MidiObjectRef obj, IntPtr str, int* /* SInt32 */ ret);
internal int GetInt (IntPtr property)
{
int val, code;

code = MIDIObjectGetIntegerProperty (handle, property, out val);
unsafe {
code = MIDIObjectGetIntegerProperty (handle, property, &val);
}
if (code == 0)
return val;
throw new MidiException ((MidiError) code);
Expand All @@ -306,13 +308,15 @@ internal void SetInt (IntPtr property, int value)
}

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIObjectGetDictionaryProperty (MidiObjectRef obj, IntPtr str, out IntPtr dict);
unsafe extern static int /* OSStatus = SInt32 */ MIDIObjectGetDictionaryProperty (MidiObjectRef obj, IntPtr str, IntPtr* dict);
internal NSDictionary? GetDictionary (IntPtr property)
{
IntPtr val;
int code;

code = MIDIObjectGetDictionaryProperty (handle, property, out val);
unsafe {
code = MIDIObjectGetDictionaryProperty (handle, property, &val);
}
if (code == 0) {
var dict = Runtime.GetNSObject (val) as NSDictionary;
if (val != IntPtr.Zero)
Expand All @@ -330,14 +334,16 @@ internal void SetDictionary (IntPtr property, NSDictionary dict)
}

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIObjectGetDataProperty (MidiObjectRef obj, IntPtr str, out IntPtr data);
unsafe extern static int /* OSStatus = SInt32 */ MIDIObjectGetDataProperty (MidiObjectRef obj, IntPtr str, IntPtr* data);

public NSData? GetData (IntPtr property)
{
IntPtr val;
int code;

code = MIDIObjectGetDataProperty (handle, property, out val);
unsafe {
code = MIDIObjectGetDataProperty (handle, property, &val);
}
if (code == 0) {
var data = Runtime.GetNSObject (val) as NSData;
if (val != IntPtr.Zero)
Expand All @@ -358,14 +364,16 @@ public void SetData (IntPtr property, NSData data)
}

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIObjectGetStringProperty (MidiObjectRef obj, IntPtr str, out IntPtr data);
unsafe extern static int /* OSStatus = SInt32 */ MIDIObjectGetStringProperty (MidiObjectRef obj, IntPtr str, IntPtr* data);

public string? GetString (IntPtr property)
{
IntPtr val;
int code;

code = MIDIObjectGetStringProperty (handle, property, out val);
unsafe {
code = MIDIObjectGetStringProperty (handle, property, &val);
}
if (code == 0) {
var ret = CFString.FromHandle (val);
if (val != IntPtr.Zero)
Expand Down Expand Up @@ -397,13 +405,15 @@ public MidiError RemoveProperty (string property)
}

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIObjectGetProperties (MidiObjectRef obj, out IntPtr dict, [MarshalAs (UnmanagedType.U1)] bool deep);
unsafe extern static int /* OSStatus = SInt32 */ MIDIObjectGetProperties (MidiObjectRef obj, IntPtr* dict, byte deep);

public NSDictionary? GetDictionaryProperties (bool deep)
{
IntPtr val;
if (MIDIObjectGetProperties (handle, out val, deep) != 0 || val == IntPtr.Zero)
return null;
unsafe {
if (MIDIObjectGetProperties (handle, &val, deep ? (byte) 1 : (byte) 0) != 0 || val == IntPtr.Zero)
return null;
}
var value = Runtime.GetNSObject (val) as NSDictionary;
CFObject.CFRelease (val);
return value;
Expand Down Expand Up @@ -446,7 +456,7 @@ protected virtual void Dispose (bool disposing)
}

[DllImport (Constants.CoreMidiLibrary)]
extern static MidiError /* OSStatus = SInt32 */ MIDIObjectFindByUniqueID (int /* MIDIUniqueID = SInt32 */ uniqueId, out MidiObjectRef obj, out MidiObjectType objectType);
unsafe extern static MidiError /* OSStatus = SInt32 */ MIDIObjectFindByUniqueID (int /* MIDIUniqueID = SInt32 */ uniqueId, MidiObjectRef* obj, MidiObjectType* objectType);

static internal MidiObject? MidiObjectFromType (MidiObjectType type, MidiObjectRef handle)
{
Expand Down Expand Up @@ -478,7 +488,11 @@ static public MidiError FindByUniqueId (int uniqueId, out MidiObject? result)
{
MidiObjectRef handle;
MidiObjectType type;
var code = MIDIObjectFindByUniqueID (uniqueId, out handle, out type);
MidiError code;

unsafe {
code = MIDIObjectFindByUniqueID (uniqueId, &handle, &type);
}
result = null;
if (code != MidiError.Ok)
return code;
Expand Down Expand Up @@ -514,9 +528,9 @@ 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);
unsafe extern static int /* OSStatus = SInt32 */ MIDIClientCreate (IntPtr str, delegate* unmanaged<IntPtr, IntPtr, void> callback, IntPtr context, MidiObjectRef* handle);
#else
extern static int /* OSStatus = SInt32 */ MIDIClientCreate (IntPtr str, MidiNotifyProc callback, IntPtr context, out MidiObjectRef handle);
unsafe extern static int /* OSStatus = SInt32 */ MIDIClientCreate (IntPtr str, MidiNotifyProc callback, IntPtr context, MidiObjectRef* handle);
#endif

[DllImport (Constants.CoreMidiLibrary)]
Expand All @@ -533,7 +547,7 @@ public class MidiClient : MidiObject {
[Deprecated (PlatformName.MacOSX, 11, 0)]
#endif
[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDISourceCreate (MidiObjectRef handle, IntPtr name, out MidiObjectRef endpoint);
unsafe extern static int /* OSStatus = SInt32 */ MIDISourceCreate (MidiObjectRef handle, IntPtr name, MidiObjectRef* endpoint);

GCHandle gch;

Expand All @@ -552,14 +566,16 @@ public MidiClient (string name)
{
using (var nsstr = new NSString (name)) {
gch = GCHandle.Alloc (this);
#if NET
int code = 0;
MidiObjectRef tempHandle;
unsafe {
code = MIDIClientCreate (nsstr.Handle, &ClientCallback, GCHandle.ToIntPtr (gch), out handle);
}
#if NET
code = MIDIClientCreate (nsstr.Handle, &ClientCallback, GCHandle.ToIntPtr (gch), &tempHandle);
#else
int code = MIDIClientCreate (nsstr.Handle, static_MidiNotifyProc, GCHandle.ToIntPtr (gch), out handle);
code = MIDIClientCreate (nsstr.Handle, static_MidiNotifyProc, GCHandle.ToIntPtr (gch), &tempHandle);
#endif
}
handle = tempHandle;
if (code != 0) {
gch.Free ();
handle = MidiObject.InvalidRef;
Expand Down Expand Up @@ -589,7 +605,10 @@ public override string ToString ()
{
using (var nsstr = new NSString (name)) {
MidiObjectRef ret;
var code = MIDISourceCreate (handle, nsstr.Handle, out ret);
int code;
unsafe {
code = MIDISourceCreate (handle, nsstr.Handle, &ret);
}
if (code != 0) {
statusCode = (MidiError) code;
return null;
Expand Down Expand Up @@ -964,10 +983,10 @@ public class MidiPort : MidiObject {
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);
unsafe extern static int /* OSStatus = SInt32 */ MIDIInputPortCreate (MidiClientRef client, IntPtr /* CFStringRef */ portName, MidiReadProc readProc, IntPtr context, MidiPortRef* midiPort);
#endif
[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIOutputPortCreate (MidiClientRef client, IntPtr /* CFStringRef */ portName, out MidiPortRef midiPort);
unsafe extern static int /* OSStatus = SInt32 */ MIDIOutputPortCreate (MidiClientRef client, IntPtr /* CFStringRef */ portName, MidiPortRef* midiPort);

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIPortDispose (MidiPortRef port);
Expand All @@ -981,19 +1000,21 @@ internal MidiPort (MidiClient client, string portName, bool input)
GCHandle gch = GCHandle.Alloc (this);
int code;

MidiPortRef tempHandle;
if (input) {
#if NET
unsafe {
MidiPortRef tempHandle;
#if NET
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);
code = MIDIInputPortCreate (client.handle, nsstr.Handle, static_MidiReadProc, GCHandle.ToIntPtr (gch), &tempHandle);
#endif
}
} else {
code = MIDIOutputPortCreate (client.handle, nsstr.Handle, out handle);
unsafe {
code = MIDIOutputPortCreate (client.handle, nsstr.Handle, &tempHandle);
}
}
handle = tempHandle;

if (code != 0) {
gch.Free ();
Expand Down Expand Up @@ -1176,13 +1197,15 @@ public nint Sources {
}

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIEntityGetDevice (MidiEntityRef handle, out MidiDeviceRef devRef);
unsafe extern static int /* OSStatus = SInt32 */ MIDIEntityGetDevice (MidiEntityRef handle, MidiDeviceRef* devRef);

public MidiDevice? Device {
get {
MidiEntityRef res;
if (MIDIEntityGetDevice (handle, out res) == 0)
return new MidiDevice (res);
unsafe {
if (MIDIEntityGetDevice (handle, &res) == 0)
return new MidiDevice (res);
}
return null;
}
}
Expand Down Expand Up @@ -1558,7 +1581,7 @@ public class MidiDevice : MidiObject {
[Deprecated (PlatformName.MacOSX, 11, 0)]
#endif
[DllImport (Constants.CoreMidiLibrary)]
extern static int MIDIDeviceAddEntity (MidiDeviceRef device, /* CFString */ IntPtr name, [MarshalAs (UnmanagedType.U1)] bool embedded, nuint numSourceEndpoints, nuint numDestinationEndpoints, MidiEntityRef newEntity);
extern static int MIDIDeviceAddEntity (MidiDeviceRef device, /* CFString */ IntPtr name, byte embedded, nuint numSourceEndpoints, nuint numDestinationEndpoints, MidiEntityRef newEntity);

public MidiEntity? GetEntity (nint entityIndex)
{
Expand All @@ -1583,7 +1606,7 @@ public int Add (string name, bool embedded, nuint numSourceEndpoints, nuint numD
if (handle == MidiObject.InvalidRef)
throw new ObjectDisposedException ("handle");
using (NSString nsName = new NSString (name)) {
return MIDIDeviceAddEntity (handle, nsName.Handle, embedded, numSourceEndpoints, numDestinationEndpoints, newEntity.Handle);
return MIDIDeviceAddEntity (handle, nsName.Handle, embedded ? (byte) 1 : (byte) 0, numSourceEndpoints, numDestinationEndpoints, newEntity.Handle);
}
}

Expand Down Expand Up @@ -2279,12 +2302,15 @@ public MidiError Received (MidiPacket [] packets)
}

[DllImport (Constants.CoreMidiLibrary)]
extern static int /* OSStatus = SInt32 */ MIDIEndpointGetEntity (MidiEndpointRef endpoint, out MidiEntityRef entity);
unsafe extern static int /* OSStatus = SInt32 */ MIDIEndpointGetEntity (MidiEndpointRef endpoint, MidiEntityRef* entity);

public MidiEntity? Entity {
get {
MidiEntityRef entity;
var code = MIDIEndpointGetEntity (handle, out entity);
int code;
unsafe {
code = MIDIEndpointGetEntity (handle, &entity);
}
if (code == 0)
return new MidiEntity (entity);
return null;
Expand Down
24 changes: 15 additions & 9 deletions src/CoreMidi/MidiThruConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ protected virtual void Dispose (bool disposing)
}

[DllImport (Constants.CoreMidiLibrary)]
static extern /* OSStatus */ MidiError MIDIThruConnectionCreate (
unsafe static extern /* OSStatus */ MidiError MIDIThruConnectionCreate (
/* CFStringRef */ IntPtr inPersistentOwnerID, /* can be null */
/* CFDataRef */ IntPtr inConnectionParams,
/* MIDIThruConnectionRef* */ out MidiThruConnectionRef outConnection);
/* MIDIThruConnectionRef* */ MidiThruConnectionRef* outConnection);

public static MidiThruConnection? Create (string persistentOwnerID, MidiThruConnectionParams connectionParams, out MidiError error)
{
Expand All @@ -75,7 +75,9 @@ protected virtual void Dispose (bool disposing)
using (var data = connectionParams.WriteStruct ()) {
var retStr = CFString.CreateNative (persistentOwnerID);
try {
error = MIDIThruConnectionCreate (retStr, data.Handle, out ret);
unsafe {
error = MIDIThruConnectionCreate (retStr, data.Handle, &ret);
}
} finally {
CFString.ReleaseNative (retStr);
}
Expand All @@ -94,17 +96,19 @@ protected virtual void Dispose (bool disposing)
}

[DllImport (Constants.CoreMidiLibrary)]
static extern /* OSStatus */ MidiError MIDIThruConnectionGetParams (
unsafe static extern /* OSStatus */ MidiError MIDIThruConnectionGetParams (
/* MIDIThruConnectionRef* */ MidiThruConnectionRef connection,
/* CFDataRef */ out IntPtr outConnectionParams);
/* CFDataRef */ IntPtr* outConnectionParams);

public MidiThruConnectionParams? GetParams (out MidiError error)
{
if (Handle == InvalidRef)
throw new ObjectDisposedException ("MidiThruConnection");

IntPtr ret;
error = MIDIThruConnectionGetParams (Handle, out ret);
unsafe {
error = MIDIThruConnectionGetParams (Handle, &ret);
}
if (error != MidiError.Ok || ret == IntPtr.Zero)
return null;
using (var data = Runtime.GetNSObject<NSData> (ret, true)) {
Expand Down Expand Up @@ -141,9 +145,9 @@ public MidiError SetParams (MidiThruConnectionParams connectionParams)
}

[DllImport (Constants.CoreMidiLibrary)]
static extern /* OSStatus */ MidiError MIDIThruConnectionFind (
unsafe static extern /* OSStatus */ MidiError MIDIThruConnectionFind (
/* CFStringRef* */ IntPtr inPersistentOwnerID,
/* CFDataRef */ out IntPtr outConnectionList);
/* CFDataRef */ IntPtr* outConnectionList);

public static MidiThruConnection []? Find (string persistentOwnerID, out MidiError error)
{
Expand All @@ -153,7 +157,9 @@ public MidiError SetParams (MidiThruConnectionParams connectionParams)
IntPtr ret;
var persistentOwnerIDHandle = CFString.CreateNative (persistentOwnerID);
try {
error = MIDIThruConnectionFind (persistentOwnerIDHandle, out ret);
unsafe {
error = MIDIThruConnectionFind (persistentOwnerIDHandle, &ret);
}
} finally {
CFString.ReleaseNative (persistentOwnerIDHandle);
}
Expand Down
15 changes: 0 additions & 15 deletions tests/cecil-tests/BlittablePInvokes.KnownFailures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,6 @@ public partial class BlittablePInvokes {
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseCreateWithSourceClock(System.IntPtr,System.IntPtr,System.IntPtr&)",
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseCreateWithSourceTimebase(System.IntPtr,System.IntPtr,System.IntPtr&)",
"CoreMedia.CMTimebaseError CoreMedia.CMTimebase::CMTimebaseGetTimeAndRate(System.IntPtr,CoreMedia.CMTime&,System.Double&)",
"CoreMidi.MidiError CoreMidi.MidiObject::MIDIObjectFindByUniqueID(System.Int32,System.Int32&,CoreMidi.MidiObjectType&)",
"CoreMidi.MidiError CoreMidi.MidiThruConnection::MIDIThruConnectionCreate(System.IntPtr,System.IntPtr,System.UInt32&)",
"CoreMidi.MidiError CoreMidi.MidiThruConnection::MIDIThruConnectionFind(System.IntPtr,System.IntPtr&)",
"CoreMidi.MidiError CoreMidi.MidiThruConnection::MIDIThruConnectionGetParams(System.UInt32,System.IntPtr&)",
"CoreServices.LSResult CoreServices.LaunchServices::LSCanURLAcceptURL(System.IntPtr,System.IntPtr,CoreServices.LSRoles,CoreServices.LSAcceptanceFlags,System.Byte&)",
"CoreVideo.CVReturn CoreVideo.CVDisplayLink::CVDisplayLinkCreateWithActiveCGDisplays(System.IntPtr&)",
"CoreVideo.CVReturn CoreVideo.CVDisplayLink::CVDisplayLinkCreateWithCGDisplay(System.UInt32,System.IntPtr&)",
Expand Down Expand Up @@ -618,17 +614,6 @@ public partial class BlittablePInvokes {
"System.Int32 CoreGraphics.CGEvent::CGGetEventTapList(System.UInt32,CoreGraphics.CGEventTapInformation*,System.UInt32&)",
"System.Int32 CoreMedia.CMBufferQueue::CMBufferQueueCreate(System.IntPtr,System.IntPtr,CoreMedia.CMBufferQueue/CMBufferCallbacks,System.IntPtr&)",
"System.Int32 CoreMedia.CMBufferQueue::CMBufferQueueCreate(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr&)",
"System.Int32 CoreMidi.MidiClient::MIDIClientCreate(System.IntPtr,method System.Void *(System.IntPtr,System.IntPtr),System.IntPtr,System.Int32&)",
"System.Int32 CoreMidi.MidiClient::MIDISourceCreate(System.Int32,System.IntPtr,System.Int32&)",
"System.Int32 CoreMidi.MidiDevice::MIDIDeviceAddEntity(System.Int32,System.IntPtr,System.Boolean,System.UIntPtr,System.UIntPtr,System.Int32)",
"System.Int32 CoreMidi.MidiEndpoint::MIDIEndpointGetEntity(System.Int32,System.Int32&)",
"System.Int32 CoreMidi.MidiEntity::MIDIEntityGetDevice(System.Int32,System.Int32&)",
"System.Int32 CoreMidi.MidiObject::MIDIObjectGetDataProperty(System.Int32,System.IntPtr,System.IntPtr&)",
"System.Int32 CoreMidi.MidiObject::MIDIObjectGetDictionaryProperty(System.Int32,System.IntPtr,System.IntPtr&)",
"System.Int32 CoreMidi.MidiObject::MIDIObjectGetIntegerProperty(System.Int32,System.IntPtr,System.Int32&)",
"System.Int32 CoreMidi.MidiObject::MIDIObjectGetProperties(System.Int32,System.IntPtr&,System.Boolean)",
"System.Int32 CoreMidi.MidiObject::MIDIObjectGetStringProperty(System.Int32,System.IntPtr,System.IntPtr&)",
"System.Int32 CoreMidi.MidiPort::MIDIOutputPortCreate(System.Int32,System.IntPtr,System.Int32&)",
"System.Int32 CoreVideo.CVDisplayLink::CVDisplayLinkTranslateTime(System.IntPtr,CoreVideo.CVTimeStamp,CoreVideo.CVTimeStamp&)",
"System.Int32 CoreVideo.CVMetalTextureCache::CVMetalTextureCacheCreate(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr&)",
"System.Int32 CoreWlan.CWKeychain::CWKeychainCopyWiFiEAPIdentity(System.IntPtr,System.IntPtr,System.IntPtr&)",
Expand Down