gpt4 book ai didi

swift - 在 Swift 中传递 C 函数回调

转载 作者:IT王子 更新时间:2023-10-29 05:42:45 24 4
gpt4 key购买 nike

如何在 Swift 中传递 C 回调?考虑这个例子:

class AudioQueue {

var desc : AudioStreamBasicDescription
var queue : AudioQueue?

func audioQueueHandleBuffer(ctx : UnsafeMutablePointer<()>,
inAQ : AudioQueue!,
inBuffer : AudioQueueBufferRef) {
// do stuff
}

func initialize() {
// this does not work!
var err = AudioQueueNewOutput(&desc, audioQueueHandleBuffer,
nil, nil, nil, 0, queue)

// ...
}
}

最佳答案

Swift 的闭包和函数绝对不是 C 函数。它们以一种奇怪的中间状态存在于 C++ 成员和 Objective-C block 之间,因此您必须将任何回调移动到 Objective-C 文件中并获取 block 或使用其他方式回调 Swift。例如,您可能有自己版本的相关 AVFoundation 函数需要一个 block :

void audioQueueHandleBuffer(void *ctx, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {
NSCAssert(ctx != NULL, @"Cannot execute NULL context block.");

void(^block)(AudioQueueRef, AudioQueueBufferRef) = (__bridge void(^)(AudioQueueRef, AudioQueueBufferRef))ctx;

return block(inAQ, inBuffer);
}

OSStatus CFIAudioQueueNewOutput(AudioStreamBasicDescription *desc, void(^callback)(AudioQueueRef, AudioQueueBufferRef), AudioQueueRef *queue) {
return AudioQueueNewOutput(desc, audioQueueHandleBuffer, (__bridge_retained void *)([callback copy]), nil, nil, 0, queue);
}

然后像您在 Swift 中期望的那样传递您的函数。

class AudioQueue {

var desc : AudioStreamBasicDescription
var queue : AudioQueueRef

func audioQueueHandleBuffer(inAQ : AudioQueueRef, inBuffer : AudioQueueBufferRef) {
// do stuff
}

func initialize() {
var err = CFIAudioQueueNewOutput(&desc, audioQueueHandleBuffer, &queue)

// ...
}
}

对于您不应该尝试在 Swift 中表达的问题,这是一个令人难以置信的痛苦解决方法。必须操作指针的代码,尤其是函数指针,最好留在 C 或 Objective-C 文件中。否则,您只是在与该语言进行一场不必要的战斗 - 特别是因为它对 C 和 Objective-C 互操作性提供了如此强大的支持。

关于swift - 在 Swift 中传递 C 函数回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25341632/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com