2016-01-27 23 views
8

Trong khi đọc thư viện Darwin trong Swift 2.2, tôi tìm thấy các mã bên dưới.'@_silgen_name' trong ngôn ngữ Swift là gì?

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

'@_silgen_name' ở dòng thứ 2 là gì?

Tôi tìm thấy thông tin bên dưới từ here, nhưng tôi muốn biết thêm thông tin chi tiết, như Thư viện nhà phát triển Apple.

Nếu nó chỉ là một tập hợp các hàm Swift bạn muốn gọi từ C, bạn có thể sử dụng thuộc tính @_silgen_name để ghi đè tên bị cắt xén, và/hoặc làm cho chúng @convention (c) sử dụng C gọi quy ước.

+0

Cảm ơn bạn rất nhiều @dfri! –

+0

Rất vui được trợ giúp :) – dfri

Trả lời

11

@_silgen_name được chỉ vừa mới đổi tên từ @asmname (see the following commit) như sau cam kết thông báo:

Điều này phản ánh một thực tế là của chỉ cho biên dịch nội bộ sử dụng thuộc tính, và không phải là thực sự tương đương với thuộc tính asm của C, vì nó không thay đổi quy ước gọi là tương thích với C.

Vì vậy, với tư cách là nhà phát triển Swift nói chung, người dùng sẽ không gặp thuộc tính này, trừ khi làm việc với, chẳng hạn, chuyển Swift sang một nền tảng khác.

Hiện tại, @_silgen_name là thuộc tính (macro) cho lớp SILGenNameAttr với các tùy chọn nhất định, trong đó tùy chọn sau là một phần của Swifts abstract syntax tree (AST). Từ swift/AST/Attr.def source code (xem thêm 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) 

Chúng tôi nhận thấy việc kê khai của SILGeneNameAttr trong 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; 
    } 
}; 

Tóm lại; nó liên quan đến việc cung cấp một giao diện Swift cho các hàm C. Bạn rất có thể sẽ gặp khó khăn khi tìm bất kỳ chi tiết nào liên quan đến SILGenNameAttr trong thư viện dành cho nhà phát triển và có thể coi đó là một tính năng không có giấy tờ.


Cuối cùng, nói chuyện sau đây với Russ Giám Mục có thể quan tâm đến bạn:

Hộp công cụ: Ở đây có thể là con rồng (34:20)

tôi sẽ không xuất xưởng này trong một ứng dụng sản xuất trong bất kỳ hoàn cảnh . Nhưng nếu bạn cảm thấy thích phiêu lưu, thì họ ở đây.

@asmname là thuộc tính để trang trí một hàm. Bạn chắc chắn cần để hiểu ABI sử dụng ứng dụng này. Swift sẽ không giúp bạn marshall các tham số rất nhiều.Trình biên dịch sẽ không bị rất tha thứ, vì vậy bạn phải đảm bảo rằng bạn đã thao tác các thông số của mình thành định dạng tương thích. Mã sau đây cho biết cách khai báo. Cung cấp thuộc tính hàm, @asmname và biểu tượng chuỗi; sau đó thực hiện các đối số của nó theo kiểu trả về. Trình biên dịch sẽ không khiếu nại nếu bạn nhận được các đối số sai hoặc trả lại nhập không chính xác. Nó chỉ hy vọng rằng biểu tượng đó tồn tại, và khi nó nhảy vào nó, tốt hơn là lấy những đối số đó và có kiểu trả về đó.

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

Q & Một (37:08)

Q: Rõ ràng không phải tất cả trong số này được ghi nhận bởi Apple, vì vậy quá trình của bạn phát hiện tất cả những hành vi này là những gì?

Russ: Trước tiên tôi sẽ xem tài liệu, nhưng bạn nói đúng là có rất nhiều nội dung không có trong đó. Nếu bạn truy cập vào Swift REPL và sử dụng cờ - Tôi nghĩ đó là một cái gì đó như -deprecated-integrated-repl - bạn có thể yêu cầu in mô-đun Swift và tất cả các bit mà Xcode không hiển thị cho bạn. Nếu bạn đào sâu vào thư mục Xcode của chuỗi công cụ, bạn cũng có thể tìm thấy nội dung trong libswiftCore và libswiftRuntime.

JP: Nếu bạn quan tâm trong thực hiện một số điều không an toàn hơn với Swift, bạn có thể thực hiện tìm kiếm mã trong GitHub cho @asmname và ngôn ngữ “Swift”, và bạn sẽ thấy một loạt các thực sự tồi tệ nhưng công cụ thú vị.

Một bài hơi cũ từ blog Giám mục:

...

Trước hết thông báo thuộc tính @asmname. Số này tương đương với DllImport hoặc extern. Nó nói với Swift rằng chúng ta sẽ liên kết trong một số thư viện xác định một hàm có tên đã cho và khớp với các đối số đã cho. "Hãy tin tôi đi Swift, tôi biết mình đang làm gì". Gợi ý: Bạn đã biết rõ hơn mình đang làm gì.

0

Để nói ngắn gọn, @_silgen_name xác định tên của hàm được hiển thị trên thư viện được chia sẻ.

Glibc.swift cho biết _swift_Glibc_open được xác định.

bạn có thể xem điều này bằng cách nm /usr/lib/swift/linux/libswiftGlibc.so như thế này.

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 
Các vấn đề liên quan