Как мне использовать dlopen и dlsym для доступа к символам из общедоступных фреймворков Apple?

#ios #dynamic #dlopen #dlsym

Вопрос:

Учитывая произвольную строку, такую как NSStringTransformToLatin , я хочу получить ссылку на глобальную переменную с соответствующим именем (документы для NSStringTransformToLatin здесь ) во время выполнения.

Это приложение для iOS, которое я создаю. Вот что я сейчас делаю:

 NSString *iOSPublicFrameworksPath = @"/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armv7";
void *iOSPublicFrameworks = dlopen([iOSPublicFrameworksPath fileSystemRepresentation], RTLD_LAZY);

char *error = dlerror();
if(error){
  NSString *errorString = [[NSString alloc] initWithUTF8String:error];
  NSLog(@"Got dlopen error: %@", errorString);
} else {
  // Where symbolName would be, for example, @"NSStringTransformToLatin".
  id value = (__bridge id)dlsym(iOSPublicFrameworks, [symbolName cStringUsingEncoding:NSUTF8StringEncoding]);
  NSLog(@"Got value: %@", value);
}
 

… Тем не менее, я считаю, что iOSPublicFrameworks это NULL так. Ошибка (отформатированная для пробелов) указывает на то, что файл не может быть найден /System/Library/Caches/com.apple.dyld/dyld_shared_cache_armv7 :

ошибка char *
«dlopen(/System/ Library/Caches/com.apple.dyld/dyld_shared_cache_armv7, 0x0001): пробовал:

‘/Users/jamie/Library/Developer/Xcode/DerivedData/ObjcRuntimeExample-afarqsmilcfpredagxvsxlqvahbg/Build/Products/Debug-iphonesimulator/dyld_shared_cache_armv7 ‘ (такого файла нет),

‘/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/introspection/dyld_shared_cache_armv7 ‘ (такого файла нет),

‘/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armv7 ‘ (такого файла нет),

‘/System/Library/Caches/com.apple.dyld/ dyld_shared_cache_armv7’ (такого файла нет), ‘/usr / lib / dyld_shared_cache_armv7’ (такого файла нет)»

Я также пытался /System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation вместо этого, но это также не удалось найти:

ошибка char *
«dlopen(/System/ Library/Frameworks/Foundation.framework / Versions / Current / Foundation, 0x0001): пробовал: ‘/Users/jamie/Library/Developer/Xcode/DerivedData/ObjcRuntimeExample-afarqsmilcfpredagxvsxlqvahbg/Build/Products/Debug-iphonesimulator/Foundation.framework / Versions/ Current /Foundation’ (такого файла нет),

‘/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework / Versions/ Current /Foundation’ (такого файла нет),

‘/System/ Library/Frameworks /Foundation.framework / Versions/ Current /Foundation’ (такого файла нет),

‘/Users/jamie/Library/Developer/Xcode/DerivedData/ObjcRuntimeExample-afarqsmilcfpredagxvsxlqvahbg/Build/Products/Debug-iphonesimulator/Foundation.framework/Versions/C/Foundation’ (no such file),

‘/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeR»…

What is the right path to use to look up symbols from the Apple public libraries (e.g. Foundation) on iOS devices? And if it depends on architecture, how do I write the path so that it adapts to the current architecture?

Note: given the option between looking in the shared cache or directly in the given Framework, I’d prefer the option of looking in the shared cache; but would like to know how to do both.