2016-01-27 11 views
8

Mentre leggevo la libreria di Darwin in Swift 2.2, ho trovato i codici seguenti.Che cos'è '@_silgen_name' nella lingua Swift?

@warn_unused_result 
@_silgen_name("_swift_Darwin_sem_open2") 
internal func _swift_Darwin_sem_open2(
    name: UnsafePointer<CChar>, 
    _ oflag: CInt 
) -> UnsafeMutablePointer<sem_t> 

Qual è '@_silgen_name' nel 2 ° linea?

Ho trovato una informazione di seguito da here, ma voglio maggiori informazioni di dettaglio, come la libreria degli sviluppatori Apple.

Se è solo un insieme specifico di funzioni Swift che si desidera chiamare da C, è possibile utilizzare l'attributo @_silgen_name per ignorare il nome storpiato, e/o @convention (c) fare per utilizzare la chiamata C convenzione.

+0

Grazie mille @dfri! –

+0

Felice di aiutare :) – dfri

risposta

11

@_silgen_name è stato recentemente rinominato da @asmname (see the following commit) con il seguente messaggio di commit:

Questo riflette il fatto che il solo per uso compilatore interno attributi, e non è davvero equivalente all'attributo C asm , poiché non modifica la convenzione di chiamata per essere compatibile con C.

Quindi, come sviluppatore Swift generico, non ci si imbatte in questo attributo, a meno che non si lavori con, ad esempio, il trasferimento di Swift su un'altra piattaforma.

Ora, @_silgen_name è un attributo (macro) per la classe SILGenNameAttr con determinate opzioni, in cui quest'ultimo è parte di Swift abstract syntax tree (AST). Dal swift/AST/Attr.def source code (vedi anche swift/lib/AST/Attr.cpp)

// Schema for DECL_ATTR: 
// 
// - Attribute name. 
// - Class name without the 'Attr' suffix (ignored for 
// - Options for the attribute, including: 
// * the declarations the attribute can appear on 
// * whether duplicates are allowed 
// * whether the attribute is considered a decl modifier or not (no '@') 
// - Unique attribute identifier used for serialization. This 
// can never be changed. 
// 
// SIMPLE_DECL_ATTR is the same, but the class becomes 
// SimpleDeclAttr<DAK_##NAME>. 
// 

DECL_ATTR(_silgen_name, SILGenName, 
      OnFunc | OnConstructor | OnDestructor | LongAttribute | 
      UserInaccessible, 0) 

Troviamo la dichiarazione di SILGeneNameAttr in swift/AST/Attr.h:

/// Defines the @_silgen_name attribute. 
class SILGenNameAttr : public DeclAttribute { 
public: 
    SILGenNameAttr(StringRef Name, SourceLoc AtLoc, SourceRange Range, bool Implicit) 
    : DeclAttribute(DAK_SILGenName, AtLoc, Range, Implicit), 
     Name(Name) {} 

    SILGenNameAttr(StringRef Name, bool Implicit) 
    : SILGenNameAttr(Name, SourceLoc(), SourceRange(), /*Implicit=*/true) {} 

    /// The symbol name. 
    const StringRef Name; 

    static bool classof(const DeclAttribute *DA) { 
    return DA->getKind() == DAK_SILGenName; 
    } 
}; 

Per riassumere; è correlato a fornire un'interfaccia Swift per le funzioni C. Molto probabilmente non riuscirai a trovare alcun dettaglio riguardante SILGenNameAttr nella libreria degli sviluppatori e potresti considerarlo una funzionalità non documentata.


Infine, il seguente colloquio con Russ Vescovo potrebbe essere di vostro interesse:

La casella degli strumenti: Qui There Be Dragons (34:20)

non vorrei mandare questo in un'applicazione di produzione in nessun circostanze. Ma se ti senti avventuroso, eccoli qui.

@asmname è un attributo per decorare una funzione. Hai sicuramente bisogno di per capire l'ABI per usare questo. Swift non ti aiuterà a marshall i parametri molto.Il compilatore non sarà molto indulgente, quindi devi assicurarti di aver manipolato i tuoi parametri in un formato con cui è compatibile. Il seguente codice mostra come dichiararlo. Assegna l'attributo della funzione, @asmname e al simbolo della stringa; quindi funzione i suoi argomenti nel tipo restituito. Il compilatore non si lamenterà se si ottengono gli argomenti errati o si restituisce il tipo in modo errato. Si aspetta solo che quel simbolo esista e, quando lo fa , è meglio prendere quegli argomenti e avere quel tipo di ritorno.

@asmname("dispatch_get_current_queue") func _get_current_queue() -> dispatch_queue_t 

Q & A (37:08)

Q: Ovviamente non tutti questi sono documentate da Apple, quindi qual è il tuo processo di scoperta di tutti questi comportamenti?

Russ: guarderò prima la documentazione, ma hai ragione che ci sono molte cose che non sono lì. Se vai al REPL di Swift e utilizzi il flag - penso che sia qualcosa come -deprecated-integrated-repl - puoi chiedere di stampare il modulo Swift e tutti i bit che Xcode non ti mostra. Se si scava nella directory Xcode di toolchain , è anche possibile trovare elementi in libswiftCore e libswiftRuntime.

JP: Se siete interessati a fare alcune cose più sicure con Swift, si può fare una ricerca codice GitHub per @asmname e la lingua “Swift”, e vedrete un sacco di veramente male, ma roba interessante.

Un po 'più vecchio post dal blog Episcopale:

...

Prima di preavviso l'attributo @asmname. Questo è l'equivalente di DllImport o extern. Dice a Swift che stiamo andando a collegare in una libreria che definisce una funzione con il nome dato e che corrisponde a gli argomenti dati. "Fidati di me, Swift, so cosa sto facendo". Suggerimento: Faresti meglio a sapere cosa stai facendo.

0

Dire breve, @_silgen_name definisce un nome della funzione indicata sulla libreria condivisa.

Glibc.swift indica che _swift_Glibc_open è definito.

potete vedere questo da nm /usr/lib/swift/linux/libswiftGlibc.so come questo.

00000000000016f0 t _swift_Glibc_fcntl 
0000000000001700 t _swift_Glibc_fcntlPtr 
00000000000016b0 t _swift_Glibc_open 
00000000000016c0 t _swift_Glibc_openat 
00000000000016d0 t _swift_Glibc_sem_open2 
00000000000016e0 t _swift_Glibc_sem_open4