2015-06-09 1 views
28

После миграции на Swift 2, я получаю эту проблему с ошибкой, заявляя, что теперь я должен использовать @convention (c) (T) -> U. Я пробовал перестановки, но пока не повезло.New @convention (c) в Swift 2: Как я могу использовать его?

func foo(context: AnyObject?, width: CGFloat) -> Int { 

} 

let bar = unsafeBitCast(foo, CFunctionPointer<(UnsafeMutablePointer<Void>, Float) -> Int>.self) 
+0

Я думаю, что должно быть возможно полностью избежать небезопасногоBitCast. Можете ли вы предоставить дополнительную информацию? Как объявляется функция C, что передается как объект контекста, ...? –

+0

Это также может быть полезно для передачи указателей объектов через обратные вызовы C: http://stackoverflow.com/questions/30786883/swift-2-unsafemutablepointervoid-to-object. –

+0

'CGFloat' - это не то же самое, что' Float'. На 64-битных платформах _ (т. Е. Каждое устройство Apple за последние несколько лет) _ это «Double», а на 32-битных платформах это «Float». Тем не менее, в Objective-C 'CGFloat' является просто простой C' typedef', поэтому вы должны просто использовать 'CGFloat' здесь. –

ответ

17

Вам больше не нужно создавать CFunctionPointer в Swift 2. Вместо этого, вы можете аннотировать тип, соглашение о вызове, в этом случае c, и использовать его непосредственно.

typealias CFunction = @convention(c) (UnsafeMutablePointer<Void>, Float) -> Int 
let bar = unsafeBitCast(foo, CFunction.self) 

Соответствующие биты @convention описания в Типе Атрибуты сечения The Swift Programming Language является:

С аргументом используется для указания ссылки на функцию С. Значение функции не имеет контекста и использует соглашение о вызове C.

+3

Спасибо. Одновременно я получил его для работы с let bar = foo как @convention (c) (AnyObject ?, CGFloat) -> Int – Laurent

+2

Er, @convention (c) (UnsafeMutablePointer ?, CGFloat) -> Int, потому что AnyObject? по-видимому, не является конвертируемым. Мне также пришлось небезопасно отображать в моей названной подписи метода. – Laurent

+0

Что значит само по себе, когда вызывается непосредственно из такого типа, как CFunction.self? –

18

Передача Swift замыкания в функцию C принимает функцию указателя параметр теперь поддерживается в Swift 2, и, как вы заметили, функция типов задаются с помощью атрибута @convention(c).

Если вы передаете закрытие непосредственно в качестве аргумента функции C, то этот атрибут выводится автоматически.

В качестве простого примера, если у вас есть эта функция C

CGFloat myCFunction(CGFloat (callback)(CGFloat x, CGFloat y)) { 
    return callback(1.1, 2.2); 
} 

, то вы можете вызвать его из Swift в

let result = myCFunction({ 
    (x, y) -> CGFloat in 
    return x + y 
}) 
print(result) // 3.3 

, который делает точно так же, как и более многословным

let swiftCallback : @convention(c) (CGFloat, CGFloat) -> CGFloat = { 
    (x, y) -> CGFloat in 
    return x + y 
} 

let result = myCFunction(swiftCallback) 
print(result) // 3.3 
+0

Как это сделать с помощью массива char? –

Смежные вопросы