#c #swift #callback
#c #swift #обратный вызов
Вопрос:
Я хочу установить пользовательскую функцию обратного вызова swift следующим образом
codecCtx.get_format = negotiatePixelFormat
где функция обратного вызова C get_format
объявляется следующим образом
var get_format: (@convention(c) (UnsafeMutablePointer<AVCodecContext>?, UnsafePointer<AVPixelFormat>?) -> AVPixelFormat)!
и моя пользовательская функция swift function выглядит так
private func negotiatePixelFormat(codecContext:AVCodecContext,pixelFormat:AVPixelFormat)->AVPixelFormat{
while pixelFormat == AV_PIX_FMT_NONE {
if pixelFormat == AV_PIX_FMT_VIDEOTOOLBOX{
if codecContext.hwaccel_context == nil{
return codecContext.pix_fmt //TBD
}
}
return pixelFormat //TBD
}
return AV_PIX_FMT_NONE //TBD
}
Но я понятия не имею, как объединить эти типы функций вместе, ни там, где я могу искать какую-то документацию.
Исходный весь код C выглядит следующим образом
codecCtx->get_format = negotiatePixelFormat
где пользовательская функция обратного вызова такая
static enum AVPixelFormat negotiate_pixel_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) {
while (*fmt != AV_PIX_FMT_NONE) {
if (*fmt == AV_PIX_FMT_VIDEOTOOLBOX) {
if (s->hwaccel_context == NULL) {
int result = av_videotoolbox_default_init(s);
if (result < 0) {
return s->pix_fmt;
}
}
return *fmt;
}
fmt;
}
return s->pix_fmt;
}
Ответ №1:
Когда вы знаете, что тип обратного вызова импортируется как:
var get_format: (@convention(c) (UnsafeMutablePointer<AVCodecContext>?, UnsafePointer<AVPixelFormat>?) -> AVPixelFormat)!
вам нужно определить функцию, которая принимает (UnsafeMutablePointer<AVCodecContext>?, UnsafePointer<AVPixelFormat>?)
и возвращает AVPixelFormat
.
Итак, вам может потребоваться объявить функцию Swift, такую как:
func negotiatePixelFormat(_ s: UnsafeMutablePointer<AVCodecContext>?, _ fmt: UnsafePointer<AVPixelFormat>?) -> AVPixelFormat {
//...
}
Насколько я вижу, ваша функция обратного вызова в C будет выглядеть следующим образом в Swift:
func negotiatePixelFormat(_ s: UnsafeMutablePointer<AVCodecContext>?, _ fmt: UnsafePointer<AVPixelFormat>?) -> AVPixelFormat {
guard let s = s, var fmt = fmt else {
return AV_PIX_FMT_NONE
}
while fmt.pointee != AV_PIX_FMT_NONE {
if fmt.pointee == AV_PIX_FMT_VIDEOTOOLBOX {
if s.pointee.hwaccel_context == nil {
let result = av_videotoolbox_default_init(s)
if result < 0 {
return s.pointee.pix_fmt
}
}
return fmt.pointee
}
fmt = 1
}
return s.pointee.pix_fmt
}
В приведенной вами информации отсутствуют некоторые детали, поэтому вам может потребоваться исправить некоторые части этого кода.
Комментарии:
1. Пока все выглядит хорошо, но теперь я получаю сообщение об ошибке «Указатель на функцию C может быть сформирован только из ссылки на «функцию» или буквальное замыкание» Редактировать: объявил его как глобальную функцию, теперь ошибка устранена.