1. 程式人生 > >iOS 使用動態庫(dylib)和動態載入framework

iOS 使用動態庫(dylib)和動態載入framework

iphone上使用動態庫的多為dylib檔案,這些檔案使用標準的dlopen方式來使用是可以的。那相同的在使用framework檔案也可以當做動態庫的方式來動態載入,這樣就可以比較自由的使用apple私有的framework了。

dlopen是開啟庫檔案

dlsym是獲取函式地址

dlclose是關閉。

當然,要使用這種方式也是有明顯缺陷的,那就是你要知道函式名和引數,否則無法繼續。

私有庫的標頭檔案可以使用class dump的方式匯出來,這個詳細的就需要google了。

下面是兩個使用的例子

1: 這是使用coreTelephony.framework獲取imsi

#define PRIVATE_PATH  "/System/Library/PrivateFrameworks/CoreTelephony.framework/CoreTelephony"

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
#if !TARGET_IPHONE_SIMULATOR
    void *kit = dlopen(PRIVATE_PATH,RTLD_LAZY);    
    NSString *imsi = nil;
    int (*CTSIMSupportCopyMobileSubscriberIdentity)() = dlsym(kit, "CTSIMSupportCopyMobileSubscriberIdentity");
    imsi = (NSString*)CTSIMSupportCopyMobileSubscriberIdentity(nil);
    dlclose(kit);    

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"IMSI" 
                                                    message:imsi 
                                                   delegate:self 
                                          cancelButtonTitle:@"OK" 
                                          otherButtonTitles:nil];
    [alert show];
    [alert release];
#endif
}

2:這是使用SpringBoardServices.framework來設定飛航模式開關

#ifdef SUPPORTS_UNDOCUMENTED_API
#define SBSERVPATH  "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
#define UIKITPATH "/System/Library/Framework/UIKit.framework/UIKit"

// Don't use this code in real life, boys and girls. It is not App Store friendly.
// It is, however, really nice for testing callbacks
+ (void) setAirplaneMode: (BOOL)status;
{
    mach_port_t *thePort;
    void *uikit = dlopen(UIKITPATH, RTLD_LAZY);
    int (*SBSSpringBoardServerPort)() = dlsym(uikit, "SBSSpringBoardServerPort");
    thePort = (mach_port_t *)SBSSpringBoardServerPort(); 
    dlclose(uikit);
    
    // Link to SBSetAirplaneModeEnabled
    void *sbserv = dlopen(SBSERVPATH, RTLD_LAZY);
    int (*setAPMode)(mach_port_t* port, BOOL status) = dlsym(sbserv, "SBSetAirplaneModeEnabled");
    setAPMode(thePort, status);
    dlclose(sbserv);
}
#endif

 本文介紹iOS SrpintBoard框架的部分私有API,具體包括:

  • 獲取ios上當前正在執行的所有Appbundle id(不管當前程式是在前臺還是後臺都可以)
  • 獲取ios上當前前臺執行的Appbundle id(不管當前程式是在前臺還是後臺都可以)
  • 根據ios appbundle id得到其App名稱、圖示(不管當前程式是在前臺還是後臺都可以)
  • 直接通過App bundle id來執行該App,無需使用url scheme(僅限當前程式在前臺時,假如程式在後臺能隨便執行其他App,那就無敵了@[email protected]

(1)初始化

    void * uikit = dlopen("/System/Library/Framework/UIKit.framework/UIKit", RTLD_LAZY);

    int (*SBSSpringBoardServerPort)() =

    dlsym(uikit, "SBSSpringBoardServerPort");

    p = (mach_port_t *)SBSSpringBoardServerPort();

    dlclose(uikit);

    sbserv = dlopen(SBSERVPATH, RTLD_LAZY);

(2)獲取iphone上所有正在執行的appbundle id列表

NSArray* (*SBSCopyApplicationDisplayIdentifiers)(mach_port_t* port, BOOL runningApps,BOOL debuggablet) =

                    dlsym(sbserv, "SBSCopyApplicationDisplayIdentifiers");

NSArray *currentRunningAppBundleIdArray= SBSCopyApplicationDisplayIdentifiers(p,NO,YES);

3)得到iphone 前臺執行的appbundle id

void* (*SBFrontmostApplicationDisplayIdentifier)(mach_port_t* port,char * result) = dlsym(sbserv, "SBFrontmostApplicationDisplayIdentifier");

char topapp[256];

SBFrontmostApplicationDisplayIdentifier(p,topapp);

currentTopAppBundleId=[NSStringstringWithFormat:@"%s",topapp];

4)根據iphone appbundle id得到其app名稱

 NSString * (*SBSCopyLocalizedApplicationNameForDisplayIdentifier)(NSString* ) =   dlsym(sbserv, "SBSCopyLocalizedApplicationNameForDisplayIdentifier");

NSString *strAppName = SBSCopyLocalizedApplicationNameForDisplayIdentifier(strBundleId);

 5)根據iphone app bundle id得到其圖示

 NSData* (*SBSCopyIconImagePNGDataForDisplayIdentifier)(NSString * bundleid) =

    dlsym(sbserv, "SBSCopyIconImagePNGDataForDisplayIdentifier");

    UIImage *icon = nil;

    NSData *iconData = SBSCopyIconImagePNGDataForDisplayIdentifier(bundleid);

    if (iconData != nil) {

        icon = [UIImage imageWithData:iconData];   

    }

    return icon;

6)直接通過app bundle id來執行該app

ios中,一個app調起另一個app的方式通常是用url scheme,但是用這個私有app,可以在不需要url scheme的情況下執行任何app

-(void)openAppByBundleId:(NSString*)bundleId

{

void* sbServices = dlopen("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_LAZY);

int (*SBSLaunchApplicationWithIdentifier)(CFStringRef identifier, Boolean suspended) = dlsym(sbServices, "SBSLaunchApplicationWithIdentifier");

    constchar *strBundleId = [bundleId cStringUsingEncoding:NSUTF8StringEncoding];

    int result = SBSLaunchApplicationWithIdentifier((__bridge CFStringRef)bundleId, NO);

    dlclose(sbServices);

}

相關推薦

iOS 使用動態(dylib)動態載入framework

在iphone上使用動態庫的多為dylib檔案,這些檔案使用標準的dlopen方式來使用是可以的。那相同的在使用framework檔案也可以當做動態庫的方式來動態載入,這樣就可以比較自由的使用apple私有的framework了。 dlopen是開啟庫檔案 dlsym

linux動態libinlcude 載入方法

       眾所周知,Linux動態庫的預設搜尋路徑是/lib和/usr/lib。動態庫被建立後,一般都複製到這兩個目錄中。當程式執行時需要某動態庫,並且該動態庫還未載入到記憶體中,則系統會自動到這兩個預設搜尋路徑中去查詢相應的動態庫檔案,然後載入該檔案到記憶體中,這

IOS 靜態.framework制作

https works select 其它 開源庫 sta cat neo working 什麽是庫? 庫是程序代碼的集合,是共享程序代碼的一種方式 根據源代碼的公開情況,庫可以分為2種類型 開源庫 公開源代碼,能看到具體實現 比如SDWebImage、AFNetwor

Linux下動態(.so)靜態(.a) 的區別 Linux下動態(.so)靜態(.a) 的區別 動態(.so)連結靜態(.a)的情況總結

Linux下動態庫(.so)和靜態庫(.a) 的區別   靜態庫在程式編譯時會被連線到目的碼中,程式執行時將不再需要該靜態庫。編譯之後程式檔案大,但載入快,隔離性也好。 動態庫在程式編譯時並不會被連線到目的碼中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在。多個

用Makefile編譯靜態檔案動態檔案

    最近要用到的簽名演算法只給了一堆原始碼沒有給庫檔案,api都不好呼叫,於是嘗試著用Makefile給一堆c原始碼編譯靜態連結庫檔案和動態連結庫檔案。 Makefile檔案編輯的相關資料連結: https://www.cnblogs.com/yya

windows下動態dll靜態編譯使用問題

window下動態庫dll和靜態庫lib問題 windows下動態庫dll和靜態庫lib的聯絡和區別,以及示例匯出個動態庫 https://blog.csdn.net/lifei092/article/details/79630273 問題: 1,生成dll時,同時生成lib是做

Go 生成C動態.so靜態.a

Go 生成C動態庫.so和靜態庫.a 原始碼 package main import "C" import "fmt" //export hello func hello(){ fmt.Println("hello world") } //export add func

linux下封裝函式——動態.so靜態.a(程式碼實現及連結方式)

在linux環境下的連結庫分為靜態連結庫(.a庫)和動態連結庫(.so庫),其作用是把C程式編譯好做成一種可執行連結檔案,主程式檔案呼叫這些程式的函式介面是可以使用a庫或so庫,在主程式中只需要include含有庫中提供的函式介面宣告的標頭檔案即可。所以學會如何

C語言中呼叫靜態函式動態函式的方式

C語言中呼叫動態庫函式的兩種方式 方式一.隱式呼叫 將動態庫的相關檔案拷貝到當前目錄下(lib、dll),然後新增以下程式碼,在程式中指定連線庫函式。 注意:第二個引數給出的是引入庫檔案(或稱“匯出庫檔案”),而不是dll。在程式執行過程中,lib將dll中需要用到的函式對映到對應的記憶

linux下靜態.a動態.so檔案的生成使用

1.靜態庫是一些目標檔案(字尾名為.o)的集合體而已。 2.靜態庫的字尾名是.a,對應於windows作業系統的字尾名為.lib的靜態庫。 3.可以使用ar命令來建立一個靜態庫檔案。 來看一個例項,根據書中的程式碼簡化的,先看一看可以編譯成庫檔案的原始檔中的程式碼: /* test.c */ i

linux設定動態路徑環境變數

linux安裝原始碼編譯出來的庫後,如何讓系統預設識別到, 如編譯後安裝在/usr/local/aarch64-qt下 1、設定動態庫連結配置 如果不設定動態庫連線,系統就找不到需要的*.so,導致軟體執行失敗。 可以ldd一下,如: [email protected]:~$ ldd

關於動態 - LIBDLL的區別與使用

http://www.cppblog.com/amazon/archive/2009/09/04/95318.html 1. 共有兩種庫 一種是LIB包含了函式所在的DLL檔案和檔案中函式位置的資訊(入口),程式碼由執行時載入在程序空間中的DLL提供,稱為動態連結庫dy

windows下使用cmakendk編譯android所用動態.so靜態.a

      不在linux上編譯android所用.a和.so,在windows上如何編譯呢?  1.準備工作:  2.開始寫一點點程式碼 使用java宣告個native函式: package android.jni.test; public class Nativ

嵌入式 Linux下的動態原理使用

1.編寫庫的標頭檔案和原始檔.   2.把所有涉及到的原始檔用如下方式編譯為目標檔案:   #  g++/gcc  -g  -c  -fPIC  -o  library1.o  library1.cpp   #  g++/gcc  -g  -c  -fPIC  -o  library2.o  libra

linux下的共享動態靜態

1.什麼是庫 在windows平臺和linux平臺下都大量存在著庫。本質上來說庫是一種可執行程式碼的二進位制形式,可以被作業系統載入記憶體執行。 由於windows和linux的本質不同,因此二者庫的二進位制是不相容的。 本文僅限於介紹linux下的庫。 2.庫的種類 linux

靜態lib動態連結dll的基礎知識

本文轉載自部落格中的一部分:原文連結 詳細內容如下: 5. 動態連結庫與靜態連結庫 一、靜態庫與動態庫        靜態連結庫就是程式在編譯的過程中將所有的物件檔案與相應庫檔案連結在一起生成可執行檔案,程式的執行不再需要其它檔案,檔案以.a的形式儲存;  

c語言生成靜態.a動態.so

在windows下動態連結庫是以.dll字尾的檔案,二在Linux中,是以.so作字尾的檔案。 動態連結庫的好處就是節省記憶體空間。 1、Linux下建立動態連結庫 在使用GCC編譯程式時,只需加上-shared選項即可,這樣生成的執行程式即為動態連結庫。 例如有檔案:he

LinuxWindows平臺 動態.so.dll文件的生成

調用dll 動態 工程 pragma 基本 重要 變量 運行 com Linux動態庫的生成 1、 純cpp文件打包動態庫 將所有cpp文件和所需要的頭文件放在同一文件夾,然後執行下面命令 gcc -shared - fpic *.c -o xxx.so; g++

mapper檔案中動態表名動態屬性的使用

mapper檔案中動態表名和動態屬性的使用   遇到一個需要在一個sql語句中實現動態表名和動態屬性的情境,在多張相似表中查詢不同name的資訊,由於我使用的是Mybatis,所以我需要在mapper檔案中實現動態表名和動態查詢。經過上網查詢,瞭解了${},#{}的原理和使用情境。但是,我在嘗試

使用gcc生成動態及使用動態的方法

gcc常用編譯選項: 選項 含義 -static 連結靜態庫,禁止使用動態庫 -shared 進行動態庫編譯,連結動態庫 -Ldir 在動態庫的搜尋路