在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
/****************************************************************************************************************/
在調用dlsym時,出現類型不符的問題。
dlsym() 返回void *
按下面這種寫法,一直報錯:
int (*addFunc)() = dlsym(kit, "add");
沒辦法,作個強制轉換:
int (*addFunc)();
*(void **)(&addFunc) = dlsym(kit, "add");
也樣就行了。
好像還可以這樣轉,比較直接:
addFunc = (int (*)())dlsym(kit, "add");