I am playing with Swift and noticed that Swift does not allow to create CFFunctionPointers. It can only pass around and reference existing ones.
As for example Core
I needed to define this callback:
typedef void (*MIDIReadProc) ( const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon );
and I wanted to use Objective-C as least as possible.
This was my approach:
MIDIReadProcCallback.h
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
typedef void (^OnCallback)(const MIDIPacketList *packetList);
@interface MIDIReadProcCallback : NSObject
+ (void (*)(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon))midiReadProc;
+ (void)setOnCallback:(OnCallback)onCallback;
@end
MIDIReadProcCallback.m
#import "MIDIReadProcCallback.h"
static OnCallback _onCallback = nil;
static void readProcCallback(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) {
if (_onCallback) {
_onCallback(pktlist);
}
}
@implementation MIDIReadProcCallback
+ (void (*)(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon))midiReadProc {
return readProcCallback;
}
+ (void)setOnCallback:(OnCallback)onCallback {
_onCallback = onCallback;
}
@end
Then you can register MIDIReadProcCallback.midiReadProc
as callback and set handler MIDIReadProcCallback.setOnCallback({ (packetList: MIDIPacketList) in ... })
Well, you can create a function pointer.
var ump = UnsafeMutablePointer<((UnsafePointer<MIDIPacketList>, UnsafeMutablePointer<Void>, UnsafeMutablePointer<Void> ) -> Void)>.alloc(1)
ump.initialize(MyMIDIReadProc)
let cp = COpaquePointer(ump)
let fp = CFunctionPointer<((UnsafePointer<MIDIPacketList>, UnsafeMutablePointer<Void>, UnsafeMutablePointer<Void> ) -> Void)>(cp)
status = MIDIDestinationCreate(midiClient,
name,
fp,
etc.
It doesn't work though with Core MIDI.
thread #7: tid = 0x713b7, 0x7a1541f0, stop reason = EXC_BAD_ACCESS (code=2, address=0x7a1541f0)
frame #0: 0x7a1541f0
frame #1: 0x00159295 CoreMIDI`LocalMIDIReceiverList::HandleMIDIIn(void*, OpaqueMIDIEndpoint*, void*, MIDIPacketList const*) + 117
BTW., you cannot have a bridging header if your MIDI code is in a framework you're writing.