> Le 1 avr. 2017 à 00:53, Joe Groff via swift-evolution > <[email protected]> a écrit : > >> >> On Mar 31, 2017, at 8:00 AM, Charles Srstka via swift-evolution >> <[email protected]> wrote: >> >> MOTIVATION: >> >> Sometimes, it’s necessary to write a top-level C function in order to >> interact with some C-based code. This can come up, for example, when making >> a new port for a cross-platform app that implements OS-dependent >> functionality via C functions. More urgently, though, it also pops up in >> certain Apple APIs, such as the standard QuickLook plug-in template. In >> order to write a QuickLook plug-in, developers are required to write >> implementations for certain predefined C functions, such as >> GeneratePreviewForURL(), GenerateThumbnailForURL(), >> CancelPreviewGeneration(), and CancelThumbnailGeneration(). Unfortunately, >> this API contract cannot be met in Swift. Currently, Swift can only expose >> class members to C/Objective-C, which means that implementing a QuickLook >> plug-in involves a rather awkward series of hoops to jump through: >> >> GeneratePreview.swift: >> >> class QLGlue: NSObject { >> @objc static func generatePreview(_: UnsafeMutableRawPointer, request >> preview: QLPreviewRequest, url: URL, contentTypeUTI: String, options: >> [String : Any]) -> OSStatus { >> // generate the preview >> } >> } >> >> GeneratePreview.m: >> >> #import “MyProject-Swift.h" >> >> OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef >> request, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) { >> return [QLGlue generatePreview:thisInterface request:request url:(__bridge >> NSURL *)url contentTypeUTI:(__bridge NSString *)contentTypeUTI >> options:(__bridge NSDictionary *)options]; >> } >> >> PROPOSED SOLUTION: >> >> Allow the @objc on top-level functions. This will cause the functions to be >> exposed as C functions, satisfying contracts such as Apple’s QuickLook >> plug-in contract, and allowing developers to just write: >> >> @objc func generatePreview(_: UnsafeMutableRawPointer, _ preview: >> QLPreviewRequest, _ url: CFURL, _ contentTypeUTI: CFString, _ options: >> CFDictionary) -> OSStatus { >> // generate the preview >> } >> >> This would eliminate an entire source file of glue code. >> >> IMPACT ON EXISTING CODE: >> >> None, since @objc is not currently allowed on top-level functions. This is >> purely additive. > > This would definitely be useful, even beyond ObjC interop. There is in fact > an unfinished implementation of a `@_cdecl("symbolName")` attribute that you > can use to export a global function as a C-compatible symbol. What's missing > (IIRC) is bridging header support to expose the declaration back to C, > compiler checking for symbol name collisions, and decoupling the validation > from ObjC interop for non-Apple platforms—and, of course, a formal evolution > proposal to make it an official part of the language. I don't think we want > to call this @objc, since it isn't inherently tied to ObjC, and IMO it makes > sense to require the exported symbol name to be required, since top-level > unmangled symbols are a crowded namespace, and it would be good to ensure > people think about the C symbol name they export. > > -Joe
We should also think about a way to specify the symbol visibility. It may be useful to export a global function to interact with C code, but that don’t mean we want to export it and make it visible outside of the module. Maybe it is enough to say that ‘internal' symbols should be exported as « private extern » and ‘public' symbol should be exported a « global », but I think it is worse mentioning it in a formal proposal.
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
