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

iphone SprintBoard部分私有API总结

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

  • 获取ios上当前正在运行的所有App的bundle id(不管当前程序是在前台还是后台都可以)
  • 获取ios上当前前台运行的App的bundle id(不管当前程序是在前台还是后台都可以)
  • 根据ios app的bundle 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上所有正在运行的app的bundle id列表

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

dlsym(sbserv, "SBSCopyApplicationDisplayIdentifiers");

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

(3)得到iphone 前台运行的app的bundle id

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

char topapp[256];

SBFrontmostApplicationDisplayIdentifier(p,topapp);

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

(4)根据iphone app的bundle 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");

const char *strBundleId = [bundleId cStringUsingEncoding:NSUTF8StringEncoding];

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

dlclose(sbServices);

}

时间: 2024-10-30 22:32:49

IOS 使用动态库(dylib)和动态加载framework的相关文章

windows动态库与Linux动态库

Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同.但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须的知道的. 两种系统动态库比较分析 Windows和Linux采用动态链接库技术 (1)动态库程序编写,在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数作为初始化的人口,通常在导出函数的声明时需要有_declspec(dllexport)关键字.Linux下的gcc编

IOS 开发下拉刷新和上拉加载更多

IOS 开发下拉刷新和上拉加载更多 简介 1.常用的下拉刷新的实现方式 (1)UIRefreshControl (2)EGOTTableViewrefresh (3)AH3DPullRefresh (4)MJRefresh (5)自己实现 2.AH3DPullRefresh实现下拉刷新和上拉下载的步骤 添加UIScrollView+AH3DPullRefresh.h 和UIScrollView+AH3DPullRefresh.m两个文件,由此可知,它是基于UIScrollView的方法. 在bu

iOS开发之下拉刷新,上拉加载更多

iOS开发之下拉刷新和上拉加载更多 1.简介(在我们常见的app中都有上拉以及下拉的操作,比例QQ,微信...所以上拉以及下拉的开源库比较多 上拉下拉开源库下载) 常用的下拉刷新的实现方式 (1)UIRefreshControl (2)EGOTableViewRefresh (3)AH3DPullRefresh (4)MJRefresh (5)自己实现 (一般情况不要自己实现,竟然有了没必要) 2.AH3DPullRefresh的使用 AH3DPullRefresh 也是一个上拉下拉开源库.使用

iOS开发之下拉刷新和上拉加载

iOS开发之下拉刷新和上拉加载 1.简介 常用的下拉刷新的实现方式 (1)UIRefreshControl (2)EGOTableViewRefresh (3)AH3DPullRefresh  (本文实例所用) (4)MJRefresh (5)自己实现 2.效果图 下拉刷新 上拉加载 3. 代码实现过程 3.1 首先添加AH3DPullRefresh到工程中, 设置UIScrollView+AH3DPullRefresh.m文件为非ARC(加入 -fno-objc-arc) 在需要添加下拉刷新的

macOS下加载动态库dylib报"code signature invalid"错误的解决办法

一.现象描述 在macOS上搞开发也有一段时间了,也积攒了一定的经验.然而,今天在替换工程中的一个动态库时还是碰到了一个问题.原来工程中用的是一个静态库,调试时发现有问题就把它替换成了动态库.这本来没什么值得一说,可工程编译完后打包测试时发现,不论怎么搞程序都加载不起来.毫无疑问,这是新替换的动态库带来的问题. 二.解决办法 于是尝试打开日志文件看看有什么发现吧: 根据上面的日志文件提示,动态库加载的时候失败了.原因为:code signature invalid.这就奇了个怪了,以前都没碰到类

热更新--动态加载framework

1.准备工作:先自己封装一个framework:http://www.cnblogs.com/sunjianfei/p/5781863.html 2.把封装好的framework压缩成zip,放到本地服务器端 3.下载压缩包,并且解压,参照:http://www.cnblogs.com/sunjianfei/p/5781799.html 4.添加并设置Application requires iPhone env.....为yes 5.动态加载下载下来的framework库文件: NSStrin

java动态编译类文件并加载到内存中

如果你想在动态编译并加载了class后,能够用hibernate的数据访问接口以面向对象的方式来操作该class类,请参考笔者的这篇博文-(该博文暂未发布) 所谓动态编译,就是在程序运行时产生java类,并编译成class文件. 一.这里介绍两种动态编译java文件的方式. 第一种:使用Runtime执行javac命令 /** * 编译java类 * 使用Runtime执行javac命令 * @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.

动态的计算行高 加载数据源 有多少显示多少 tableView 包含 colloctionView 显示复杂的界面写法

有时候,我们经常碰到这样的需求 先遵守代理 @interface PublishCollectionCell ()<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout> 创建 _layout = [[UICollectionViewFlowLayout alloc] init]; //        layout.scrollDirection = UICollecti

使用FireBreath生成的.dll库出现“*.dll模块加载失败”

好不容易可以再FireBreath里面使用sip库eXosip. 在本地使用没有问题,但是在别的机子上面安装.dll库的时候就出现了问题: 我猜想,可能是和我加入的库有关系,之前没有加入其它的库的时候,是成功的. 于是,我把eXosip的里面2个动态库放进来,奇迹出现了 Windows下面对静态库和动态库的使用还不是很清楚...