亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 編程 > Swift > 正文

淺談在Swift中關(guān)于函數(shù)指針的實(shí)現(xiàn)

2020-03-09 17:50:14
字體:
供稿:網(wǎng)友
這篇文章主要介紹了淺談在Swift中關(guān)于函數(shù)指針的實(shí)現(xiàn),是作者根據(jù)C語(yǔ)言的指針特性在Swifft中做出的一個(gè)實(shí)驗(yàn),需要的朋友可以參考下
 

Swift沒有什么?

蘋果工程師給我建的唯一一堵墻是:在Swift中沒有任何辦法獲得一個(gè)函數(shù)的指針:

    注意,C函數(shù)指針不會(huì)導(dǎo)入到Swift中(來自“Using Swift with Cocoa and Objective-C“)

但是我們?cè)趺粗肋@種情況下鉤子的地址和跳到哪呢?讓我們深入了解一下,并且看看Swift的func在字節(jié)碼層面上的是什么。

當(dāng)你給一個(gè)函數(shù)傳遞一個(gè)泛型參數(shù)時(shí),Swift并沒有直接傳遞它的地址,而是一個(gè)指向trampoline函數(shù)(見下文)并帶有一些函數(shù)元數(shù)據(jù)信息的指針。并且trampoline自己是包裝原始函數(shù)的結(jié)構(gòu)的一部分。

這是什么意思?

讓我們用它來舉個(gè)例子:
 

復(fù)制代碼代碼如下:

func call_function(f : () -> Int) {
    let b = f()
}
 
func someFunction() -> Int {
    return 0
}

 

在Swift里我們只寫 call_function(someFunction).
但是 Swift 編譯器處理代碼后,性能比調(diào)用call_function(&someFunction)好很多
 

復(fù)制代碼代碼如下:

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);

 

一個(gè)包裝器的結(jié)構(gòu)如下:  
 

復(fù)制代碼代碼如下:

struct swift_func_wrapper {
    uint64_t **trampoline_ptr_ptr; // = &trampoline_ptr
    uint64_t *trampoline_ptr;
    struct swift_func_object *object;
}

 

什么是 swift_func_object類型? 為了創(chuàng)建對(duì)象,Swift 實(shí)時(shí)使用了一個(gè)全局的叫metadata[N]的的常量(每一個(gè) function調(diào)用都是唯一的,似的你的func 作為一個(gè)泛型的參數(shù),所以對(duì)于如下的代碼:  
 

復(fù)制代碼代碼如下:

func callf(f: () -> ()) {
    f();
}
callf(someFunction);
callf(someFunction);

 

常量metadata和metadata2會(huì)被創(chuàng)建).

一個(gè)metadata[N]的結(jié)構(gòu)有點(diǎn)兒像這樣this:
 

復(fù)制代碼代碼如下:

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; 
}

 

最初metadataN只有2個(gè)字段集合:destructor_func 和 type。前者是一個(gè)函數(shù)指針,將用作為使用swift_allocObject() 創(chuàng)建的對(duì)象分配內(nèi)存。后者是對(duì)象類型識(shí)別器(函數(shù)或方法的0x40 或者 '@'),并且是(某種形式)被swift_allocObject() 用來創(chuàng)建一個(gè)正確的對(duì)象給我們的func:  
 
swift_allocObject(&metadata2->type, 0x20, 0x7);

一旦func 對(duì)象被創(chuàng)建,它擁有下面的結(jié)構(gòu):
 

復(fù)制代碼代碼如下:

struct swift_func_object {
    uint64_t *original_type_ptr;
    uint64_t *unknown0;
    uint64_t function_address;
    uint64_t *self;
}

 

第一個(gè)字段是一個(gè)指針,用來對(duì)應(yīng)metadata[N]->type 的值,第二個(gè)字段似乎是 0x4 | 1 << 24(0x100000004) 并且暗示一些可能 (我不知道是什么)。  function_address 是我們實(shí)際掛鉤感興趣的地方,并且self 是 (立即) 自己的指針 (如果我們的對(duì)象表示一個(gè)普通的函數(shù),這個(gè)字段是 NULL)。


好,那么這段我從框架開始如何?事實(shí)上,我不明白為什么Swift運(yùn)行時(shí)需要它們,但不論如何,這就是它們?cè)鷳B(tài)的樣子:
 

復(fù)制代碼代碼如下:

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;
}

 

讓我們創(chuàng)建它

想象一下,在你的Swift代碼中有這些函數(shù):

 

復(fù)制代碼代碼如下:

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

 

而且你想像這樣生成它們:
 

復(fù)制代碼代碼如下:

takesFunc(someFunction)

 

這一行代碼會(huì)轉(zhuǎn)換成相當(dāng)大的C程序:
 

復(fù)制代碼代碼如下:

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);

 

結(jié)構(gòu)體“swift_func_type_metadata”很不透明,因此我也沒太多可以說的。

回到函數(shù)指針

既然我們已經(jīng)知道函數(shù)怎樣作為一個(gè)泛型類型參數(shù)表示,讓我們借助這個(gè)打到你的目的:獲取一個(gè)真正指向函數(shù)的指針!

我們要做的只是需要注意,我們已經(jīng)擁有一個(gè)作為第一個(gè)參數(shù)傳遞的trampoline_ptr指針域地址,所以object域的偏移量只是0x8。其他的所有都很容易組合:
 

復(fù)制代碼代碼如下:

uint64_t _rd_get_func_impl(void *trampoline_ptr)
{
    struct swift_func_object *obj = (struct swift_func_object *)*(uint64_t *)(trampoline_ptr + 0x8);
 
    return obj->function_address;
}

 

看起來是時(shí)候?qū)憣?/p>

 

復(fù)制代碼代碼如下:

rd_route(
    _rd_get_func_impl(firstFunction),
    _rd_get_func_impl(secondFunction),
    nil
)

 

但我們?cè)鯓訌腟wift中調(diào)用這些C函數(shù)呢?

為此,我們將使用Swift非公開的特性:允許我們提供給C函數(shù)一個(gè)Swift接口的@asmname屬性。用法如下:
 

復(fù)制代碼代碼如下:

@asmname("_rd_get_func_impl")
    func rd_get_func_impl<Q>(Q) -> UInt64;  
 
@asmname("rd_route")
    func rd_route(UInt64, UInt64, CMutablePointer<UInt64>) -> CInt;

 

這就是我們?cè)赟wift中使用rd_route()需要的一切。

但是它不能處理任何函數(shù)!

也就是說,你不能用rd_route()鉤住任何帶有泛型參數(shù)的函數(shù)(這可能是Swift的bug,也可能不是,我還沒弄清楚)。但是你可以使用extensions輕松的覆蓋它們,直接指定參數(shù)的類型:
 

復(fù)制代碼代碼如下:

class DemoClass {
    class func template <T : CVarArg>(arg : T, _ num: Int) -> String {
        return "/(arg) and /(num)";
    }
}
 
DemoClass.template("Test", 5) // "Test and 5"
 
extension DemoClass {
    class func template(arg : String, _ num: Int) -> String {
        return "{String}";
    }
    class func template(arg : Int, _ num: Int) -> String {
        return "{Int}";
    }
}
 
-- Your extension's methods for String and Int will be preferred over the original ones */
DemoClass.template("Test", 5) -- "{String}"
DemoClass.template(42, 5) -- "{Int}"
-- But for other types `template(T, Int)` will be used
DemoClass.template(["Array", "Item"], 5) --- "[Array, Item] and 5"

 

SWRoute

為了在Swift里輕松地勾住函數(shù),我創(chuàng)建了一個(gè)名為SWRoute的封裝體—它只是一個(gè)小類和一個(gè)我們之前寫過的C函數(shù):

 

復(fù)制代碼代碼如下:
_rd_get_func_impl():
 
class SwiftRoute {
    class func replace<MethodT>(function targetMethod : MethodT, with replacement : MethodT) -> Int
    {
        return Int(rd_route(rd_get_func_impl(targetMethod), rd_get_func_impl(replacement), nil));
    }
}

 

注意,我們無償進(jìn)行類型檢查因?yàn)镾wift需要目標(biāo)方法和替換具有相同的MethoT類型。

而且我們也無法使用一個(gè)復(fù)制的原始實(shí)現(xiàn),因此我只能把nil作為另一個(gè)參數(shù)傳給函數(shù)rd_route()。如果你對(duì)如何把這個(gè)指針集成到Swift代碼有自己的看法,麻煩告訴我!

你可以在資源庫(kù)中找到大量SWRoute的實(shí)例。

這就是所有的了。



注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到swift教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
国产裸体舞一区二区三区| 情趣网站视频在线观看| 日批视频免费播放| 国产偷人妻精品一区二区在线| 成人好色电影| 在线视频欧美日韩| 国产视频一区在线观看| 国产亚洲欧美日韩俺去了| 国产成人在线看| 久久福利影院| 国产精品色在线网站| 成人av国产| 免费又爽又黄禁片视频1000片| 美女又黄又免费的视频| 成人美女在线视频| 国内精品久久久久久久久电影网| 精品日韩成人av| 日韩精品一区二区在线观看| 精品自在线视频| 欧产日产国产精品98| 中文综合在线观看| 久久久成人的性感天堂| 四季av一区二区| 国产精品久久久久久影院8一贰佰| 午夜诱惑痒痒网| 欧美最猛黑人xxxx黑人猛交3p| 激情成人在线视频| 亚洲小说图片| 视频一区在线观看| 久久99精品久久久久久园产越南| 好男人www社区在线视频夜恋| 天天免费亚洲黑人免费| 老司机在线看片网av| 麻豆国产一区二区三区四区| 一本在线高清不卡dvd| 在线免费黄色| 国产精品美女久久| 日韩成人精品一区| jizz性欧美2| 欧美日韩国产免费一区二区| 中文字幕久精品免| 91青草视频久久| 欧美一区二区三区久久久| 欧洲精品在线观看| 91人人网站| 日韩欧美视频在线免费观看| 久久免费激情视频| 欧美一区二区三区久久综| 欧美三级韩国三级日本一级| 欧美国产日韩在线观看| 欧美激情一区三区| 最近2018年中文字幕在线| 国产日韩欧美夫妻视频在线观看| 97人妻精品一区二区三区免费| 91青娱乐在线视频| 久久视频一区二区| 欧美日韩一区二区国产| 欧美极品aaaaabbbbb| 久久影视三级福利片| 亚洲高清不卡一区| 亚洲最大的av网站| 里番全彩acg☆无翼乌全彩3d| 二区三区不卡不卡视频| 一区二区视频欧美| 8x国产一区二区三区精品推荐| 在线观看日韩视频| 人人干视频在线| 性日韩欧美在线视频| 日韩精品视频一区二区三区| 亚洲欧美日本国产有色| 亚洲第一狼人区| 天堂网在线最新版www中文网| 国产一区二区视频免费观看| 国产一二三区在线观看| 午夜精品久久久久久久99樱桃| 国产欧美一区二区精品久久久| 不卡av免费在线观看| 国产一区二区三区免费| xxxx日韩| 四虎成人免费电影| av鲁丝一区鲁丝二区鲁丝三区| 91精品国产91久久久久久久久| 日本午夜精品| 97一区二区三区| 波多野结衣欧美| 韩日精品中文字幕| 中国成人亚色综合网站| 完美搭档在线观看| 日韩中文字幕免费在线观看| 国产传媒视频在线| 黄色一级大片在线免费看产| 欧美人与物videos另类xxxxx| 欧美激情一区二区三区在线视频观看| 日韩精品在线电影| 国产日韩精品视频一区二区三区| 亚洲最大视频网| 91免费在线视频观看| 中文字幕久热在线精品| 中文在线√天堂| 污视频网站在线看| 三区在线视频| 青青热久免费精品视频在线18| 思热99re视热频这里只精品| 欧美日韩一级黄色片| 欧美日韩老妇| 亚洲一卡二卡三卡四卡| 毛片基地黄久久久久久天堂| 欧美日韩直播| 国产精品手机播放| 日韩中文字幕观看| 91精品1区2区| 日本精品一区二区三区在线播放视频| 麻豆av一区二区三区久久| 日韩精品一区二区三区在线| 最近中文字幕在线免费观看| 国产精选在线观看| 国产啪精品视频网站| www.一区二区三区.com| 美女黄色一级视频| 欧美18xxxxx| 在线日韩国产网站| 牛人国产偷窥女洗浴在线观看| 国产精品国产精品| 亚洲新中文字幕| 日韩电影中文字幕在线观看| 性欧美xxxx视频在线观看| 欧洲日韩一区二区三区| 亚洲的天堂在线中文字幕| 国产丝袜一区| missav|免费高清av在线看| 1024精品合集| 91激情在线| 99久久夜色精品国产亚洲1000部| 国产黄色小视频| 美女扒开大腿让男人桶| 久久先锋资源| 欧美一级xxxx| 三级小视频在线观看| 久久精品理论片| 五月天电影免费在线观看一区| 欧美偷拍一区二区三区| 全球成人免费直播| 欧美五码在线| 成人精品一区二区三区电影免费| 91精品国产高清久久久久久91裸体| 中文字幕欧美亚洲| 亚洲天堂网一区| 亚洲精品成人a| 中日精品一色哟哟| 亚洲一区中文在线| 五月开心婷婷久久| 99在线热播精品免费| 国模一区二区三区私拍视频| 宅男噜噜噜66一区二区| 欧美 日韩 国产 在线观看| 97免费在线观看视频| 日韩久久中文字幕| 福利视频网站一区二区三区| 亚洲av无码久久精品色欲| 天天想你在线观看完整版电影免费| 色综合视频在线观看| 亚洲国产日日夜夜| 青青草原网站在线观看| 天天天天天天操| 日韩av在线天堂网| 国产精品午夜剧场| 亚洲综合专区| 欧美三级视频| 91麻豆精品国产无毒不卡在线观看| 免费看久久久| 人与牲动交xxxbbb| 日本一区午夜艳熟免费| 美女与牲口做爰视频在线观看| 国内精品国产三级国产aⅴ久| 91精品国产自产在线老师啪| 色8久久影院午夜场| 亚洲欧美一二三| 久久365资源| 福利写真视频网站在线| 男人扒开美女尿口无遮挡图片| 欧美综合一区二区三区| 十八禁视频网站在线观看| 日本高清www| 国产美女玉足交| 中文幕一区二区三区久久蜜桃| 一区视频二区视频| www婷婷av久久久影片| 97人妻精品一区二区三区动漫| 一区二区在线观看免费视频播放| 成人做爰66片免费看网站| 日韩美女在线看| 久久免费黄色网址| 超碰97久久国产精品牛牛| 国产精品亚洲lv粉色| 一区二区三区精品视频在线观看| 免费看污黄网站在线观看| 91久久人澡人人添人人爽欧美| 欧美情侣在线播放| 亚洲一卡二卡在线观看| 国产丝袜视频在线播放| 亚洲免费综合| 久久久噜噜噜www成人网| 一日本道久久久精品国产| 中文字幕在线观看2018| 国产不卡视频一区| 黄色国产在线观看| 狠狠色丁香久久婷婷综| 永久免费看mv网站入口78| 欧美视频在线观看 亚洲欧| 91视频成人免费| 国模精品一区二区| 午夜精品av| 欧美私人网站| 午夜一区在线| 日韩国产一级片| 精人妻一区二区三区| 久久精品一区二区免费播放| 国产日产欧美一区| 欧美插插视频| 国产精品chinese在线观看| 欧美va久久久噜噜噜久久| 日韩电影网站| 人妖一区二区三区| 国产精品chinese在线观看| 在线午夜精品自拍| 久久激情五月激情| 日本69式三人交| 国产日韩中文在线| 欧美高清一级片在线| 成人美女av在线直播| 亚洲第一狼人区| 软萌小仙自慰喷白浆| 久久久亚洲精品石原莉奈| 8x8ⅹ国产精品一区二区二区| 国产精品嫩草影院在线看| xxav国产精品美女主播| 中文字幕一区二区三区免费看| 国产精品xxxxxx| 国产视频久久网| 最近2019年好看中文字幕视频| 亚洲欧美激情一区二区| 91美女片黄在线观看游戏| 高清一级毛片视频| 国内精品久久久久久野外| 成人永久看片免费视频天堂| 欧美一个色资源| 色视频在线播放| 国产日产欧美精品一区二区三区| 欧美成人性色生活仑片| 女人抽搐喷水高潮国产精品| 欧美日韩一区二区在线| 中文字幕日韩在线| 亚洲成熟少妇视频在线观看| 日韩中文字幕精品| 亚洲精品在线a| 亚洲一区在线观看视频| 日韩不卡一区| 亚欧精品在线视频| 久久超碰99| 日本卡一卡2卡3卡4精品卡网站| 精品人妻一区二区三区四区| 99re6热在线精品视频| 2021天堂中文幕一二区在线观| 国产精品久久久久影视| 国产精品久久久久不卡| 亚洲免费一区二区| 欧美做爰猛烈大尺度视频| 国产精品高潮久久| 女人色在线免费视频| www在线免费观看视频| 黑人与亚洲人色ⅹvideos| 嫩草影院国产精品| 国产精自产拍久久久久久蜜| 1314成人网| 国产日产久久高清欧美一区| 中文字幕欧美人妻精品一区蜜臀| 久久精品国产免费看久久精品| 国产精品视频线看| 毛片在线看片| 国内不卡的二区三区中文字幕| 日韩一区二区三区三四区视频在线观看| 成人天堂yy6080亚洲高清| 久久香蕉精品视频| 国产一级淫片久久久片a级| 伊人久久大香线蕉综合网站| 国内精品久久久久影院一蜜桃| 性孕妇free特大另类| 亚洲热av色在线播放| 欧美精品videosbestsex另类| 日日夜夜精品网站| 国内精品400部情侣激情| 亚洲成人久久久| 久久久综合网| 国内视频精品| 公交车上扒开嫩j挺进去| 免费av观看网站| 中文字幕精品一区二区三区在线| 黄色av电影在线播放| 中文字幕av一区二区三区高| 欧美日韩p片| 欧美一区日本一区韩国一区| 一区二区三区 日韩| 欧洲成人在线视频| 丰满爆乳一区二区三区| 久久黄色小视频| 亚洲中文字幕无码爆乳av| 51精品视频一区二区三区| 蝌蚪视频在线播放| 国产精品福利在线观看网址| 久久人人爽爽爽人久久久| 成人免费在线视频网| 午夜一级电影| 亚洲一级视频在线观看| 小草av在线播放| 欧美一级做一级爱a做片性| 国产高清不卡av| 久久这里只精品最新地址| 亚洲一区二区三区无吗| 少妇高潮一区二区三区99| 青青草综合视频| 亚洲影院色在线观看免费| 激情亚洲色图| 久久a级毛片毛片免费观看| 不卡av日日日| 亚洲线精品一区二区三区| 丁香婷婷自拍| 91久久久久国产一区二区| xxxxaaa欧美另类|