> 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
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution