• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >swift > 浅谈在Swift中关于函数指针的实现

浅谈在Swift中关于函数指针的实现

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了浅谈二次函数,浅谈函数的一致连续性,浅谈三角函数,浅谈一次函数,swift 回调函数等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Swift没有什么?

苹果工程师给我建的唯一一堵墙是:在Swift中没有任何办法获得一个函数的指针:

    注意,C函数指针不会导入到Swift中(来自“Using Swift with Cocoa and Objective-C“)

但是我们怎么知道这种情况下钩子的地址和跳到哪呢?让我们深入了解一下,并且看看Swift的func在字节码层面上的是什么。

当你给一个函数传递一个泛型参数时,Swift并没有直接传递它的地址,而是一个指向trampoline函数(见下文)并带有一些函数元数据信息的指针。并且trampoline自己是包装原始函数的结构的一部分。

这是什么意思?

让我们用它来举个例子:
  func call_function(f : () -> Int) {
    let b = f()
}
 
func someFunction() -> Int {
    return 0
}</div>

在Swift里我们只写 call_function(someFunction).
但是 Swift 编译器处理代码后,性能比调用call_function(&someFunction)好很多
  struct swift_func_wrapper *wrapper =  ... /* configure wrapper for someFunction() */
struct swift_func_type_metadata *type_metadata = ... /* information about function's arguments and return type */
call_function(wrapper->trampoline, type_metadata);</div>

一个包装器的结构如下:  
  struct swift_func_wrapper {
    uint64_t **trampoline_ptr_ptr; // = &trampoline_ptr
    uint64_t *trampoline_ptr;
    struct swift_func_object *object;
}</div>

什么是 swift_func_object类型? 为了创建对象,Swift 实时使用了一个全局的叫metadata[N]的的常量(每一个 function调用都是唯一的,似的你的func 作为一个泛型的参数,所以对于如下的代码:  
  func callf(f: () -> ()) {
    f();
}
callf(someFunction);
callf(someFunction);</div>

常量metadata和metadata2会被创建).

一个metadata[N]的结构有点儿像这样this:
  struct metadata {
    uint64_t *destructor_func;
    uint64_t *unknown0;
    const char type:1; // I'm not sure about this and padding,
    char padding[7];   // maybe it's just a uint64_t too...
    uint64_t *self;
}</div>

最初metadataN只有2个字段集合:destructor_func 和 type。前者是一个函数指针,将用作为使用swift_allocObject() 创建的对象分配内存。后者是对象类型识别器(函数或方法的0x40 或者 '@'),并且是(某种形式)被swift_allocObject() 用来创建一个正确的对象给我们的func: 
 
swift_allocObject(&metadata2->type, 0x20, 0x7);

一旦func 对象被创建,它拥有下面的结构:
  struct swift_func_object {
    uint64_t *original_type_ptr;
    uint64_t *unknown0;
    uint64_t function_address;
    uint64_t *self;
}</div>

第一个字段是一个指针,用来对应metadata[N]->type 的值,第二个字段似乎是 0x4 | 1 << 24(0x100000004) 并且暗示一些可能 (我不知道是什么)。  function_address 是我们实际挂钩感兴趣的地方,并且self 是 (立即) 自己的指针 (如果我们的对象表示一个普通的函数,这个字段是 NULL)。


好,那么这段我从框架开始如何?事实上,我不明白为什么Swift运行时需要它们,但不论如何,这就是它们原生态的样子:
  void* someFunction_Trampoline(void *unknown, void *arg, struct swift_func_object *desc)
{
    void* target_function = (void *)desc->function_address;
    uint64_t *self = desc->self;
 
    swift_retain_noresult(desc->self); // yeah, retaining self is cool!
    swift_release(desc);
 
    _swift_Trampoline(unknown, arg, target_function, self);
    return unknown;
}
 
void *_swift_Trampoline(void *unknown, void *arg, void *target_function, void *self)
{
    target_function(arg, self);
    return unknown;
}</div>

让我们创建它

想象一下,在你的Swift代码中有这些函数:

  func takesFunc<T>(f : T) {
    ...
}
func someFunction() {
    ...
}</div>

而且你想像这样生成它们:
  takesFunc(someFunction)</div>

这一行代码会转换成相当大的C程序:
  struct swift_func_wrapper *wrapper = malloc(sizeof(*wrapper));
wrapper->trampoline_ptr     = &someFunction_Trampoline;
wrapper->trampoline_ptr_ptr = &(wrapper.trampoline);
wrapper->object = ({
    // let's say the metadata for this function is `metadata2`
    struct swift_func_object *object = swift_allocObject(&metadata2->type, 0x20, 0x7);
    object->function_address = &someFunction;
    object->self = NULL;
    object;
});
 
 
// global constant for the type of someFunction's arguments
const void *arg_type = &kSomeFunctionArgumentsTypeDescription;
// global constant for the return type of someFunction
const void *return_type = &kSomeFunctionReturnTypeDescription;
 
struct swift_func_type_metadata *type_metadata = swift_getFunctionTypeMetadata(arg_type, return_type);
 
takesFunc(wrapper->trampoline_ptr, type_metadata);</div>

结构体“sw

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 浅谈在Swift中关于函数指针的实现

相关文章

  • 2017-05-28Mybatis传list参数调用oracle存储过程的解决方法
  • 2017-05-28在Swift中使用Cocoa的现有设计模式介绍
  • 2017-05-28Hibernate三种状态和Session常用的方法
  • 2017-05-28用Swift编写自动录音器
  • 2017-05-28Swift 3.0基础学习之闭包
  • 2017-05-28Swift 中闭包的简单使用
  • 2017-05-22Swift 可选(Optionals)类型
  • 2017-05-28Swift、Objective-C、Cocoa混合编程设置指南
  • 2017-05-28jstl之map,list访问遍历以及el表达式map取值的实现
  • 2017-05-28初步理解Swift中的泛型

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Swift 数据类型
    • Swift用final关键字来防止重写
    • 程序迁移到swift 3.0的一些实用技巧
    • Swift3.0 GCD定时器的使用DEMO
    • 解析Swift语言面相对象编程中的继承特性
    • Swift教程之类与结构详解
    • Swift中Optional值的链式调用学习笔记
    • JVM 体系结构详解
    • 查看import的类是出自哪个jar包的方法
    • Swift心得笔记之控制流

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有