在ios上调用dlopen

时间:2015-02-18 08:21:35

标签: ios iphone dylib

这是一个备受关注的话题,尤其是最近的话题。希望这不是一个骗局,因为我已经讨论了所有其他的SO问题。

我对这是否合法不感兴趣。虽然不清楚你是否可以在iOS8上使用dylib自由地做你想要的东西,但是看起来允许有一些动态加载(参见例如Can you build dynamic libraries for iOS and load them at runtime?)。

我关心的只是让dlopen工作(暂时忘记商店提交)!我有一个非常基本的iOS示例,我手动执行dlopen,然后使用dlsym来调用本地dylib中的函数。这在模拟器上工作正常但在设备上失败。该设备是运行(非越狱)iOS 7.1.2的iPhone 4s。

AFAIK甚至在iOS 7上调用dlopen也是合法的,因为有明确的Apple指示如何支持这一点(请参阅“{在旧版本的iOS中部署包含应用程序”https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW3)。

我的猜测是根本原因很简单,就像dylib在iOS不喜欢二进制文件的文件夹中一样。有没有人有这方面的经验,知道有什么限制,或者可能知道我做错了什么。

仅供参考我的加载代码是:

NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
NSString* dlPath = [NSString stringWithFormat: @"%@/frameworktest", resourcePath];
const char* cdlpath = [dlPath UTF8String];
void* hModule = dlopen(cdlpath, RTLD_LAZY);

dylib(frameworktest)是通过创建Cocoa Touch Framework,从构建的框架构建和获取dylib二进制文件并添加到项目资源(在根文件夹中)创建的。 otool将dylib显示为针对ios min版本7.0的armv7 dynmic库。我也可以成功地打开文件,所以我知道我正在查找正确的文件夹。

我可以深入了解dlopen程序集。到目前为止,事实上它变得没有信息,寻找明显的失败:)

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

在调用dlopen之后检查errno我看到EPERM(我猜不是很大的惊喜)。

我已经为构建添加了一个代码签名阶段,以明确签署dylib并且它现在可以正常工作。

一些额外信息:有趣的是,应用程序的签名阶段默认运行在整个.app包上,而不仅仅是主应用程序二进制文件(从未仔细查看过)。所以人们可能会期望这也会签署dylib。事实上,当我的自定义阶段运行代码签名报告"替换现有的签名"。然而,这可能来自框架的原始构建。我检查了该项目的阶段,并且框架也签署了(再次,不仅仅是dylib,而是将整个框架传递给codesign)。符号参数是相同的。因此,我认为,沿着小道的某处,dylib的签名不正确。我会在某个时候对此进行更详细的调查,如果有任何有趣的信息,请回复。我的猜测是我通过手动创建,提取和打包dylib来打破系统!

感谢@jww和@duskwuff的建议!