什么是' @_ silgen_name'用Swift语言?

时间:2016-01-27 07:18:15

标签: swift darwin

在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>

什么是&#39; @_ silgen_name&#39;在第二行?

我在here找到了以下信息,但我想了解更多详细信息,例如Apple Developer Library。

  

如果它只是您要从C调用的一组特定Swift函数,则可以使用@_silgen_name属性覆盖损坏的名称,和/或使它们@convention(c)使用C调用约定。< / p>

2 个答案:

答案 0 :(得分:16)

@_silgen_name最近刚刚从@asmnamesee the following commit)重命名,其中包含以下提交消息:

  

这反映了属性的仅适用于   编译器内部使用,并不等同于C的asm   属性,因为它不会更改调用约定   C兼容。

因此,作为一般的Swift开发人员,除非使用Swift移植到其他平台,否则不会遇到此属性。

现在,@_silgen_name是具有特定选项的类SILGenNameAttr的属性(宏),后者是Swifts abstract syntax tree (AST)的一部分。来自swift/AST/Attr.def source code(另请参阅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)

我们在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使用这个。斯威夫特不会帮助你   非常重要的参数。编译器不会   非常宽容,所以你必须确保你已经操纵了你的   将参数转换为与其兼容的格式。以下代码   显示如何声明它。给出函数属性@asmname和   字符串符号;然后在返回类型中运行其参数。该   如果你的参数错误或返回,编译器不会抱怨   输入不正确。它只期望该符号存在,何时存在   跳转到它,最好采用这些参数并具有返回类型。

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

Q&amp; A(37:08)

     

显然,Apple并未记录所有这些内容,那么您发现所有这些行为的过程是什么?

     

Russ :我会先看一下文档,但你说的很多东西都没有。如果你去斯威夫特   REPL并使用旗帜 - 我认为它就像   -deprecated-integrated-repl - 您可以要求它打印Swift模块以及Xcode没有显示的所有位。如果你深入了解   工具链目录Xcode,你也可以在libswiftCore和   libswiftRuntime。

     

JP :如果您对使用Swift做一些不安全的事情感兴趣,可以在GitHub中为@asmname和语言进行代码搜索   “斯威夫特”,你会看到一堆非常糟糕但有趣的东西。

来自Bishops博客的稍微过时的帖子:

  

...

     

首先注意@asmname属性。这相当于   DllImportextern。它告诉Swift我们将要链接   一些库,用于定义具有给定名称和匹配的函数   给定的论点。 “只要相信我斯威夫特,我知道我在做什么”。   提示:你最好知道自己在做什么。

答案 1 :(得分:1)

简而言之, @_silgen_name定义共享库上显示的函数名称。

Glibc.swift告诉_swift_Glibc_open已定义。

你可以通过nm /usr/lib/swift/linux/libswiftGlibc.so这样看到这一点。

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