2013-08-28 2 views
3

Я пытаюсь создать динамическую библиотеку для iOS и загрузить ее во время выполнения. Посмотрев на this question и this answer, я делаю это с помощью iOSOpenDev и развертывания всего на моем iPhone. Xcode проект для dylib называется KDylibTwo и файлы I modiefied являются:iOS 6.1 Создание и связь динамической библиотеки

KDylibTwo.h

#import <Foundation/Foundation.h> 

@interface KDylibTwo : NSObject 
-(void)run; 
@end 

KDylibTwo.m

#import "KDylibTwo.h" 

@implementation KDylibTwo 

-(id)init 
{ 
    if ((self = [super init])) 
    { 
    } 

    return self; 
} 

-(void)run{ 
    NSLog(@"KDylibTwo loadded."); 
} 

@end 

Для того, чтобы проверить, если мой библиотека работает, после ее создания для профилирования (способ, которым iOSOpenDev развертывает его на iPhone), я могу найти его на моем устройстве в /usr/lib/libKDylibTwo.dylib и построить настройку (снова используя iOSOpenDev), Зацепив трамплин следующим образом:

#include <dlfcn.h> 

%hook SBApplicationIcon 

-(void)launch{ 
    NSLog(@"\n\n\n\n\n\n\nSBHook For libKDylibTwo.dylib"); 

    void* dylibLink = dlopen("/usr/lib/libKDylibTwo.dylib", RTLD_NOW); 

    if(dylibLink == NULL) { 
     NSLog(@"Loading failed."); 
    } else { 
     NSLog(@"Dylib loaded."); 

     void (*function)(void); 
     *(void **)(&function) = dlsym(dylibLink, "run"); 
     if (function) { 
      NSLog(@"Function found."); 
      (*function)(); 
     } else { 
      NSLog(@"Function NOT found"); 
     } 
    } 

    NSLog(@"End of code"); 
    %log; 
    %orig; 
} 

%end 

После установки твика на устройстве и нажав на иконке (что бы огнь зацепил код), выход консоли выглядит следующим образом:

Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: SBHook For libKDylibTwo.dylib 
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: Dylib loaded. 
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: Function NOT found 
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: End of code 
Aug 28 13:03:35 Pudge SpringBoard[18254] <Warning>: -[<SBApplicationIcon: 0x1d5008c0> launch] 

Моих вопрос в том, что я делаю неправильно, и функция библиотеки не вызывается или не выполняется! Я думаю, я должен уточнить, что я говорю только о джейлбрейк-устройствах, а не о разработке App Store, поэтому, пожалуйста, не отправляйте сообщения о том, что это невозможно!

Благодарим вас,
Panagiotis.

+0

Я не дома и не могу проверить прямо сейчас. Но, Виктор прав, что техника, которую я показал, предназначена для вызова функций C, а не Obj-C. – Nate

ответ

6

Как указал Виктор Ронин, «dlsym» предназначен для символов C. Чтобы получить класс цели-c из dylib, который вы связали во время выполнения, вы можете использовать функции выполнения objc. В вашем случае:

void* dylibLink = dlopen("/usr/lib/libKDylibTwo.dylib", RTLD_NOW); 
id KDylibTwo = [[objc_getClass("KDylibTwo") alloc] init]; 
[KDylibTwo run]; 

Первая строка связывает вашу библиотеку во время выполнения. Это необходимо для использования кода внутри него.

Вторая строка создает экземпляр класса KDylibTwo. objc_getClass Функция возвращает объект класса, который впоследствии можно использовать для создания экземпляров этого класса, как и для любого класса объектива-C, используя методы alloc и init. Как только вы получили объект класса с objc_getClass, вы можете работать с ним, как будто ничего не случилось. На этом этапе вы можете забыть, что вы динамически связывали свою библиотеку во время выполнения.

Третья линия вызывает run метод. Как вы можете видеть, это обычный объективный синтаксис C. Ничего не изменилось, потому что вы связали свою библиотеку во время выполнения.Вы можете вызвать любой метод, который вы хотите.

+0

Большое вам спасибо! Работает отлично и не нужно подписывать SMS! Но как я могу сделать вызов определенной функции, которую я хотел бы запустить из своей библиотеки, и отправить или получить данные? Возможно, что-то связано с переменной 'dylibLink', которая, кажется, не используется. – Panagiotis

+0

Можете ли вы уточнить, чего именно вы хотите достичь? – creker

+1

Что касается подписания, для моего кода требуется право на работу. Если вы протестировали его, загрузив dylib в трамплин, тогда у вас уже есть это право. SpringBoard уже содержит его. Если вы собираетесь связать этот dylib с вашим приложением, ему нужно это право или оно не сработает. – creker

2

Я никогда не использовал dlsym, чтобы получить указатель на объектный метод c (я считаю, что невозможно вызвать объективный метод c через dlsym, но я могу ошибаться).

Однако самый важный бит информации о том, что вторым параметром dlsym должно быть имя символа.

Название символа «run» будет работать только для функции C. Что-то вроде:

EXPORT void run() 
{ 
NSLog(@"Run"); 
} 

метода объекта C имеет более сложные имена символов и, как я уже сказал, я не уверен, что они могут быть переданы ли dlsym вообще.

+0

Я думаю, что вы правы. Но просто попробовал (используя Theos для dylib, чтобы избежать заголовков Objective-C и прочее), добавив только функцию, как вы ее заявили, и, к сожалению, я получаю тот же результат. – Panagiotis

+0

Я считаю, что он должен быть отмечен также ЭКСПОРТОМ. Я рекомендую прочитать эту статью о динамических библиотеках для OS X (учитывая, что iOS имеет одно и то же/очень похожее ядро) - https://developer.apple.com/library/mac/documentation/developertools/conceptual/dynamiclibraries/100 -Articles/CreateDynamicLibraries.html # // apple_ref/doc/uid/TP40002073-SW1 –

+0

ЭКСПОРТ должен быть определен во-первых, но опять же, не помогает! '#define EXPORT __attribute __ ((видимость (« по умолчанию »)))' – Panagiotis

Смежные вопросы