Objective-C包装器,用于CFunctionPointer到Swift Closure [英] Objective-C Wrapper for CFunctionPointer to a Swift Closure

查看:234
本文介绍了Objective-C包装器,用于CFunctionPointer到Swift Closure的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在玩Swift并注意到Swift不允许创建CFFunctionPointers。它只能传递和参考现有的。



例如CoreAudio要求CFunctionPointer接受某些回调,因此我不能使用纯Swift。



所以我需要使用一些Objective-C trampoline或wrapper,这里使用一个Swift Closure作为参数以及原始的回调原型,然后可以分配为回调,但实际上操作发生在Swift而不是Objective-C。



如何做到这一点?



这样的包装器的一些示例代码将帮助我理解可以使用来自目标C的Swift代码以灵活的方式来解决Swift无法创建CFunctionPointers。



是的,我知道我可以写东西需要在Objective-C。我想在纯Swift中做一个学习练习,将我的一个应用程序移植到Swift(使用很多CoreAudio / CoreVideo框架)。

解决方案<我需要定义这个回调:

  typedef void(* MIDIReadProc)(const MIDIPacketList * pktlist,void * readProcRefCon,void * srcConnRefCon); 

,我想尽可能使用Objective-C。



这是我的方法:



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

  #importMIDIReadProcCallback.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

c $ c> MIDIReadProcCallback.midiReadProc 作为回调和设置处理程序 MIDIReadProcCallback.setOnCallback({(packetList:MIDIPacketList)in ...}) p>

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 CoreAudio requires CFunctionPointer to certain callbacks therefore I cannot use pure Swift.

So I need to use some Objective-C trampoline or wrapper here that takes a Swift Closure as a parameter as well as the original callback prototype and then can be assigned to be the callback, but the actually action happens in Swift and not Objective-C.

How do I do this?

Some example code for such a wrapper would help me to understand how I can use Swift code from objective C for such purposes in a flexible way to work around Swift not being able to create CFunctionPointers.

Yes, I know I can just write stuff when needed in Objective-C. I want to do it in pure Swift as a learning exercise porting one of my apps to Swift (uses a lot of CoreAudio/CoreVideo framework).

解决方案

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 ... })

这篇关于Objective-C包装器,用于CFunctionPointer到Swift Closure的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆