在Swift 2.2中阅读Darwin库时,我发现了以下代码。
@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”是什么?
我从这里找到了以下信息,但是我想要更多详细信息,例如Apple Developer Library。
如果只是要从C调用的一组特定的Swift函数,则可以使用@_silgen_name属性覆盖改写的名称,和/或使它们成为@convention(c)以使用C调用约定。
@_silgen_name最近才使用以下提交消息从@asmname(请参见以下提交)重命名:
@_silgen_name
@asmname
这反映了以下事实:该属性 仅供编译器内部使用 ,并且实际上并不等效于C的asm属性,因为它不会将调用约定更改为与C兼容。
因此,作为一名普通的Swift开发人员,除非有将Swift移植到其他平台的经验,否则就不会遇到这个属性。
现在,@_silgen_name是SILGenNameAttr具有某些选项的类的属性(宏),其中后者是Swifts 抽象语法树(AST)的一部分。从swift/AST/Attr.def源代码(另请参见swift / lib / AST / Attr.cpp)
SILGenNameAttr
swift/AST/Attr.def
// 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)
我们SILGeneNameAttr在swift / AST / Attr.h中找到的声明:
SILGeneNameAttr
/// 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; } };
总结一下; 它与为C函数提供Swift接口有关。您很可能很难SILGenNameAttr在开发人员库中找到有关的任何详细信息,并且可以将其视为未记录的功能。
最后,您可能会感兴趣与Russ Bishop进行以下对话:
工具箱:这里有龙(34:20) 在任何情况下,我都不会在生产应用程序中交付此产品。但是,如果您喜欢冒险,那就来吧。 @asmname是装饰函数的属性。您绝对需要了解ABI才能使用此工具。Swift不会非常帮助您整理参数。编译器不会太宽容,因此必须确保已将参数操纵为兼容的格式。以下代码显示了如何声明它。给出函数属性,@asmname和字符串符号;然后将其参数用作返回类型。如果您输入的参数错误或返回类型错误,编译器将不会抱怨。它仅期望该符号存在,并且当它跳转到它时,最好采用这些参数并具有该返回类型。 @asmname("dispatch_get_current_queue") func _get_current_queue() -> dispatch_queue_t 问答(37:08) 问 : 显然,并非所有记录都由Apple记录,那么发现所有这些行为的过程如何? 拉斯 :我先看一下文档,但是您说对了,那里没有很多东西。如果您转到Swift REPL并使用该标志(我想这是类似的东西 -deprecated-integrated- repl),则可以要求它打印Swift模块以及Xcode不会向您显示的所有位。如果深入工具链目录Xcode,您还可以在libswiftCore和libswiftRuntime中找到东西。 JP :如果您有兴趣使用Swift做更多不安全的事情,可以在GitHub中搜索代码@asmname和语言“ Swift”,您会看到很多非常糟糕但有趣的东西。
工具箱:这里有龙(34:20)
在任何情况下,我都不会在生产应用程序中交付此产品。但是,如果您喜欢冒险,那就来吧。
@asmname是装饰函数的属性。您绝对需要了解ABI才能使用此工具。Swift不会非常帮助您整理参数。编译器不会太宽容,因此必须确保已将参数操纵为兼容的格式。以下代码显示了如何声明它。给出函数属性,@asmname和字符串符号;然后将其参数用作返回类型。如果您输入的参数错误或返回类型错误,编译器将不会抱怨。它仅期望该符号存在,并且当它跳转到它时,最好采用这些参数并具有该返回类型。
@asmname("dispatch_get_current_queue") func _get_current_queue() ->
dispatch_queue_t
问答(37:08)
问 : 显然,并非所有记录都由Apple记录,那么发现所有这些行为的过程如何?
拉斯 :我先看一下文档,但是您说对了,那里没有很多东西。如果您转到Swift REPL并使用该标志(我想这是类似的东西 -deprecated-integrated- repl),则可以要求它打印Swift模块以及Xcode不会向您显示的所有位。如果深入工具链目录Xcode,您还可以在libswiftCore和libswiftRuntime中找到东西。
-deprecated-integrated- repl
JP :如果您有兴趣使用Swift做更多不安全的事情,可以在GitHub中搜索代码@asmname和语言“ Swift”,您会看到很多非常糟糕但有趣的东西。
Bishops博客的一篇稍旧的文章:
… 首先,请注意@asmname属性。这等于 DllImport或extern。它告诉Swift,我们将链接到一些库,该库定义具有给定名称并匹配给定参数的函数。 “请相信我Swift,我知道我在做什么” 。提示:您最好知道自己在做什么。
…
首先,请注意@asmname属性。这等于 DllImport或extern。它告诉Swift,我们将链接到一些库,该库定义具有给定名称并匹配给定参数的函数。 “请相信我Swift,我知道我在做什么” 。提示:您最好知道自己在做什么。
DllImport
extern