> 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

Reply via email to