在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’是什么?
我从here找到了以下信息,但我想要更多详细信息,比如Apple Developer Library.
If it’s just a specific set of Swift functions you want to call from C,you can use the @_silgen_name attribute to override the mangled name,and/or make them @convention(c) to use the C calling convention.
@_silgen_name最近刚刚从@asmname(
see the following commit)重命名,并带有以下提交消息:
This reflects the fact that the attribute’s only for
compiler-internal use,and isn’t really equivalent to C’s asm
attribute,since it doesn’t change the calling convention to be
C-compatible.
因此,作为一般的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的谈话感兴趣:
> Unsafe Swift: For Fun & Profit
The Toolbox: Here there be dragons (34:20)
I would not ship this in a production application under any
circumstances. But if you’re feeling adventurous,here they are.
@asmname
is an attribute to decorate a function. You definitely need
to understand the ABI to use this one. Swift will not help you
marshall the parameters very much. The compiler is not going to be
very forgiving,so you have to make sure that you’ve manipulated your
parameters into a format it’s compatible with. The following code
shows how to declare it. Give the function attribute,@asmname
,and
the string symbol; then function its arguments in return type. The
compiler will not complain if you get the arguments wrong or return
type incorrectly. It only expects that that symbol exists,and when it
jumps to it,it better take those arguments and have that return type.
06002
Q&A (37:08)
Q: Obviously not all of these are documented by Apple,so what’s your process of discovering all these behaviors?
Russ: I’ll look at the documentation first,but you’re right that there is a lot of stuff that isn’t in there. If you go to the Swift
REPL and use the flag — I think it’s something like
-deprecated-integrated-repl
— you can ask it to print the Swift module and all the bits that Xcode doesn’t show you. If you dig into the
toolchain directory Xcode,you can also find stuff in libswiftCore and
libswiftRuntime.
JP: If you’re interested in doing some more unsafe things with Swift,you can do a code search in GitHub for @asmname
and language
“Swift”,and you’ll see a bunch of really bad but interesting stuff.
来自Bishops博客的一篇略微更老的帖子:
> Swift – Don’t do this.
…
First off notice the @asmname
attribute. This is the equivalent of
DllImport
or extern
. It tells Swift that we are going to link in
some library that defines a function with the given name and matching
the given arguments. “Just trust me Swift,I know what I’m doing”. Hint: You had better know what you’re doing.