问题
This is a much talked about subject, particularly of late. Hopefully this isn't a dupe as I've gone over all the other SO questions.
I'm not interested in whether this is legal or not. Whilst it's not 100% clear whether you can freely do what you want with a dylib on iOS8, it appears some amount of dynamic loading is allowed (see for example Can you build dynamic libraries for iOS and load them at runtime?).
What I care about is just making dlopen work (forget store submissions for now)! I've got a very basic iOS example where I manually do a dlopen followed by a dlsym to call a function in a homegrown dylib. This works fine on the simulator but fails on device. The device is an iPhone 4s running (non-jailbroken) iOS 7.1.2.
AFAIK it is legal to call dlopen even on iOS 7 as there are explicit Apple instructions for how to support this (see "Deploying a Containing App to Older Versions of iOS" here https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW3).
My guess is the root cause is something simple, like the dylib being in a folder which iOS doesn't like for binaries. Does anyone have any experience doing this and know what the restrictions are, or possibly knows what I'm doing wrong.
FYI my load code is:
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
NSString* dlPath = [NSString stringWithFormat: @"%@/frameworktest", resourcePath];
const char* cdlpath = [dlPath UTF8String];
void* hModule = dlopen(cdlpath, RTLD_LAZY);
The dylib (frameworktest) was created by creating a Cocoa Touch Framework, building and grabbing the dylib binary from the built framework and adding to the project resources (in the root folder). otool shows the dylib as an armv7 dynmic library targeting ios min version of 7.0. I can successfully fopen the file as well so I know I'm looking in the right folder.
I can step deep into the dlopen assembly. So far in fact that it became uninformative looking for obvious fails :)
Any ideas?
回答1:
Checking errno after the call to dlopen I see EPERM (not a big surprise I guess).
I've added a codesign phase to the build to explicity sign the dylib and it works now.
Some extra info: Interestingly, the sign phase for the app defaults to running over the whole .app bundle, not just the main app binary (never looked closely at that). So one might expect this to sign the dylib as well. In fact, when my custom phase runs codesign reports "replacing existing signature". However this might be coming from the original build of the framework. I checked the phases for that project and the framework is also signed (again, not just the dylib but the whole framework is passed to codesign). The sign parameters are the same. So somewhere along the trail the dylib is getting signed incorrectly I guess. I'll investigate this in more detail at some point and post back if there's any interesting info. My guess is I'm breaking the system by manually creating, extracting and packaging the dylib!
Thanks to @jww and @duskwuff for the suggestions!
来源:https://stackoverflow.com/questions/28578957/calling-dlopen-on-ios