JAL
JAL

Reputation: 42449

Can I use @_silgen_name to expose an [Objective-]C or C++ symbol that is not a function to Swift?

Consider a private CFLocaleKey that is later bridged as an NSLocaleKey (NSString) for use internally with NSLocale:

CF_EXPORT const CFLocaleKey kCFLocaleTemperatureUnit API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

CFLocale_Private.h

The most obvious way to reference something like this would be through a bridging header. But is there a way to reference this CF/NSLocaleKey with pure Swift using something like @_silgen_name?

First I tried:

@_silgen_name("NSLocaleTemperatureUnit")
public let temperatureUnit: NSLocale.Key

But the compiler complains:

@_silgen_name cannot be applied to this declaration

Ok, let's make it static, but static properties can only be declared on a type. So I tried setting it up in the way the other NSLocaleKey values are bridged to Swift, as an extension on NSLocale.Key:

extension NSLocale.Key {
    @_silgen_name("NSLocaleTemperatureUnit")
    public static let temperatureUnit: NSLocale.Key
}

Even with this, the compiler complains with the same error as above. This is where I got stuck. Does @_silgen_name only work for functions? Is what I'm asking even possible with pure Swift?

Upvotes: 2

Views: 789

Answers (1)

JAL
JAL

Reputation: 42449

As of writing (August 8th, 2017), this currently is not possible with any version of Swift (3 or 4).

Without a header declaration, clang isn't sure how to map something in Swift back to C. @_silgen_name and @_cdecl work on functions, but not for variables.

This was confirmed by Jordan Rose, a Swift compiler engineer at Apple on Twitter.

tl;dr:

anything but func is hard.

Upvotes: 1

Related Questions