2016-01-27 32 views
8

Podczas czytania biblioteki Darwin w Swift 2.2, znalazłem poniżej kody.Co to jest "@_silgen_name" w języku Swift?

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

Co to jest "@ nazwa_ilenu" w drugiej linii?

Znalazłem poniżej informacje z here, ale chcę więcej informacji szczegółowych, takich jak Apple Developer Library.

Jeśli to tylko specyficzny zestaw funkcji Swift chcesz zadzwonić z C, można użyć atrybutu @_silgen_name przesłonić zniekształconej nazwy, i/lub ich @convention (c) używać C powołanie Konwencja.

+0

Dziękuję bardzo @dfri! –

+0

Z przyjemnością pomogę :) – dfri

Odpowiedz

11

@_silgen_name została niedawno zmieniona z @asmname (see the following commit) z następującymi popełnić wiadomości:

Odzwierciedla to fakt, że atrybutu tylko dla kompilator użytku wewnętrznego, i nie jest to odpowiednik atrybutu C ASm , ponieważ nie zmienia konwencji wywołującej, aby była zgodna z C.

Tak więc, jako generalny programista Swift, nie spotkałby się z tym atrybutem, chyba że z, na przykład, przeniesieniem Swifta na inną platformę.

Teraz, @_silgen_name jest atrybutem (makro) dla klasy SILGenNameAttr z pewnymi opcjami, gdzie ten drugi jest częścią Swifts abstract syntax tree (AST). Od swift/AST/Attr.def source code (patrz również 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) 

Znajdziemy deklarację SILGeneNameAttr w 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; 
    } 
}; 

Podsumowując; Jest to związane z zapewnieniem interfejsu Swift dla funkcji C. Najprawdopodobniej trudno będzie znaleźć jakiekolwiek szczegóły dotyczące SILGenNameAttr w bibliotece programistów i można uznać to za nieudokumentowaną funkcję.


Wreszcie, po rozmowy z Russ biskupem może być interesujące dla Ciebie:

Przybornik: Tu Be Dragons (34:20)

Nie wysyłam to w aplikacji produkcyjnej w żadnym okolicznościach. Ale jeśli czujesz się na siłach, oto one.

@asmname to atrybut do dekorowania funkcji. Zdecydowanie potrzebujesz , aby zrozumieć ABI, aby użyć tej. Swift nie pomoże ci bardzo dokładnie określić parametrów.Kompilator nie będzie bardzo wybaczający, więc musisz upewnić się, że zmanipulowałeś parametry w formacie, który jest zgodny. Poniższy kod przedstawia sposób deklaracji. Nadaj atrybutowi funkcji: @asmname i symbol ciągu; następnie używaj jego argumentów w typie zwrotnym. Kompilator nie będzie narzekał, jeśli otrzymasz niepoprawne argumenty lub niepoprawnie zwrócisz . Oczekuje tylko, że ten symbol istnieje, a kiedy przeskoczy do niego, to lepiej wziąć te argumenty i mieć ten typ zwracany.

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

Q & (37:08)

Q: Oczywiście nie wszystkie z nich są udokumentowane przez firmę Apple, więc jaki jest twój proces odkrywania tych wszystkich zachowań?

Russ: Najpierw przyjrzę się dokumentacji, ale masz rację, że jest dużo rzeczy, których tam nie ma. Jeśli przejdziesz do SWIFT REPL i użyjesz flagi - myślę, że jest to coś w stylu: -deprecated-integrated-repl - możesz poprosić ją o wydrukowanie modułu Swift i wszystkich bitów, które Xcode Ci nie pokazuje. Jeśli zagłębisz się w katalogu Xcode narzędzia toolchain, możesz również znaleźć rzeczy w bibliotekach libswiftCore i libswiftRuntime.

JP: Jeśli jesteś zainteresowany w jakiejś bardziej niebezpieczne rzeczy z Swift, można wykonać wyszukiwanie kodu w GitHub dla @asmname i języka „Swift”, a zobaczysz kilka naprawdę złe, ale interesujące rzeczy.

Nieco starszy post z bloga Episkopatu:

...

pierwsze zawiadomienie atrybut @asmname. Jest to odpowiednik DllImport lub extern. Mówi Swiftowi, że mamy zamiar połączyć w pewną bibliotekę, która definiuje funkcję o podanej nazwie i dopasowując podane argumenty do . "Zaufaj mi, Swift, wiem, co robię". Wskazówka: Lepiej wiesz, co robisz.

0

Krótko mówiąc, @_silgen_name definiuje nazwę funkcji widocznej w udostępnianej bibliotece.

Glibc.swift mówi, że zdefiniowano _swift_Glibc_open.

można to zobaczyć przez nm /usr/lib/swift/linux/libswiftGlibc.so w ten sposób.

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