2015-06-09 24 views
28

Sau khi chuyển sang Swift 2, tôi gặp vấn đề này với một lỗi nói rằng bây giờ tôi nên sử dụng @convention (c) (T) -> U. Tôi đã thử hoán vị nhưng cho đến nay không có may mắn.New @convention (c) trong Swift 2: Làm thế nào tôi có thể sử dụng nó?

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

} 

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

Tôi nghĩ rằng có thể tránh được hoàn toàn không an toànBitCast. Bạn có thể cung cấp thêm một số thông tin? Hàm C được khai báo như thế nào, cái gì được truyền như đối tượng ngữ cảnh, ...? –

+0

Điều này cũng có thể hữu ích khi truyền con trỏ đối tượng qua C callbacks: http://stackoverflow.com/questions/30786883/swift-2-unsafemutablepointervoid-to-object. –

+0

'CGFloat' không giống với' Float'. Trên nền tảng 64 bit _ (nghĩa là mỗi thiết bị của Apple trong vài năm qua) _ đó là một nền tảng 'Double' và 32 bit, đó là một' Float'. Tuy nhiên, trong Objective-C 'CGFloat' chỉ là một chữ cái' C kiểu chữ ', vì vậy bạn chỉ nên sử dụng 'CGFloat' ở đây. –

Trả lời

17

Bạn không còn cần phải tạo ra một CFunctionPointer trong Swift 2. Thay vào đó, bạn có thể chú thích kiểu của bạn bằng cách gọi quy ước, trong trường hợp này c, và sử dụng nó trực tiếp.

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

Các bit có liên quan của @convention mô tả trong Loại phần Thuộc tính tổng The Swift Programming Language là:

Đối số c được sử dụng để chỉ ra một tài liệu tham khảo chức năng C. Giá trị hàm không mang ngữ cảnh và sử dụng quy ước gọi C.

+3

Cảm ơn. Đồng thời, tôi đã làm việc với let bar = foo như @convention (c) (AnyObject ?, CGFloat) -> Int – Laurent

+2

Er, @convention (c) (UnsafeMutablePointer ?, CGFloat) -> Int vì AnyObject? không thể chuyển đổi được. Tôi đã phải unsafebitcast trong chữ ký phương pháp được gọi của tôi quá. – Laurent

+0

Có nghĩa là gì khi được gọi trực tiếp từ một loại như CFunction.self? –

18

Đi qua một đóng Swift để một hàm C tham gia một chức năng tham số con trỏ hiện đang được hỗ trợ trong Swift 2, và, như bạn thấy, chức năng loại được chỉ định với các thuộc tính @convention(c).

Nếu bạn vượt qua một đóng cửa trực tiếp như một đối số cho hàm C thì thuộc tính này được suy ra tự động.

Là một ví dụ đơn giản, nếu bạn có chức năng C này

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

sau đó bạn có thể gọi nó từ Swift như

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

mà thực hiện chính xác giống như các tiết hơn

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

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

Làm thế nào để làm điều này với mảng char? –

Các vấn đề liên quan