因为接触的项目经常需要用到别人写的framework和dylib,所以今天要写的东西是如何在App内部实现调用外部动态库文件,如果刚好你也在研究这个,也希望可以对你有帮助喔。
PS:毕竟我是自学小白出身,好多东西都是自己摸索,有不对的地方还请一笑而过. ??
App调用动态库方法:
方法一的模式比较单纯好理解,就不做介绍了。这里记录的是方法二,因为觉得方法二比较有意思。
下面开始,go go go.
Dylib
首先创建一个dylib-->(dylibTry),需要定义相关的类的实现,这里我为了demo演示只单纯的写了一个echo方法(sayHello),你可以关联跟多类,将你最终的需求实现导入一个对外的类header中,然后通过dlopen 加载资源,指定call 该类.
void *libHandle; char *error; libHandle = NULL; libHandle = dlopen(LIB_CACULATE_PATH, RTLD_NOW); if (libHandle == NULL) { error = dlerror(); NSLog(@"dlopen error: %s", error); } else { NSLog(@"dlopen load dylib success."); } Class PublicAPIClass = NSClassFromString(@"dylibTry"); if (!PublicAPIClass) { NSLog(@"Unable to load class"); return 0; } NSObject *publicAPIObject = [PublicAPIClass new]; [publicAPIObject performSelector:@selector(sayHello)];
结果如下:
2020-03-18 10:23:59.508749+0800 runDylibTest[68522:655761] dlopen load dylib success.2020-03-18 10:23:59.509079+0800 runDylibTest[68522:655761] Enter Self Init2020-03-18 10:23:59.509182+0800 runDylibTest[68522:655761] Hello,萧蔷ink
直接创建object 然后去call class method是不是很直接喔
Framwork
一样,你需要创建一个framwork,定义内部的相关类实现,这里我也创建了一个person的类,一样的echo 方法,只不过这里用到的是NSBundle去load资源。
NSError *error = nil; NSBundle *frameworkBundle = [NSBundle bundleWithPath:bundlePath]; if (frameworkBundle && [frameworkBundle loadAndReturnError:&error]) { NSLog(@"Load framework successfully"); }else { NSLog(@"Failed to load framework with err: %@",error); return -1; } Class PublicAPIClass = NSClassFromString(@"Person"); if (!PublicAPIClass) { NSLog(@"Unable to load class"); return 0; } NSObject *publicAPIObject = [PublicAPIClass new]; [publicAPIObject performSelector:@selector(sayHello)];
结果如下:
2020-03-18 10:32:50.610453+0800 runDylibTest[69866:667880] Load framework successfully2020-03-18 10:32:50.610858+0800 runDylibTest[69866:667880] Enter Self Init2020-03-18 10:32:50.610935+0800 runDylibTest[69866:667880] Hello,萧蔷ink1
上面就是2种方式加载调用外部动态库文件,到这里,我还想到了一些问题,OC是怎么做到这个资源分配实现的,以后有机会我会去探索了解这些内部的机制,对于小白的我来说,还是先学会走路吧。 : - )