2013-12-08 2 views
3

Работая с Xcode, я ищу, чтобы реэкспортировать символ (функцию специально) из двоичного пакета mach-o, где символ изначально определен в dylib.Как реэкспортировать символ dylib из зависимого пакета

Я попытался -sub_library переключатель компоновщика, но это, кажется, не реэкспорт символы dylib, вероятно, потому что я не строить dylib сам (?)

И реэкспорт-л/Переключатели reexport_library, похоже, не поддерживаются в компоновщике Xcode.

Любые идеи?

ответ

3

Это может быть то, что вы ищете, если я правильно вас понял. Я буду использовать libpthread в качестве гипотетического dylib, содержащего функции, которые вы хотите реэкспортировать.

mybundle.c:

#include <pthread.h> 
#include <stdio.h> 
void *foo(void *ctx) { 
    puts((char *)ctx); 
    return 0; 
} 

mybundle.exp:

_foo 
_pthread_create 
_pthread_join 

Компиляция сверток, динамически ссылки на libpthread.dylib:

josh$ gcc -bundle -lpthread -Wl,-exported_symbols_list,mybundle.exp -o mybundle.so mybundle.c 

myloader.c:

#include <dlfcn.h> 
#include <pthread.h> // merely for type definitions 
#include <assert.h> 
#include <stdio.h> 

int main() { 
    void *(*foo)(void *ctx); 
    /* the following cannot be declared globally without changing their names, 
     as they are already (and unnecessarily) declared in <pthread.h> */ 
    int (*pthread_create)(pthread_t *thrd, const pthread_attr_t *attr, void *(*proc)(void *), void *arg); 
    int (*pthread_join)(pthread_t thrd, void **val); 

    void *bundle; 
    assert(bundle = dlopen("mybundle.so", RTLD_NOW)); 
    assert(foo = dlsym(bundle, "foo")); 
    assert(pthread_create = dlsym(bundle, "pthread_create")); 
    assert(pthread_join = dlsym(bundle, "pthread_join")); 

    pthread_t myThrd; 
    pthread_create(&myThrd, 0, foo, "in another thread"); 
    pthread_join(myThrd, 0); 

    return 0; 
} 

Компиляция погрузчик:

josh$ gcc myloader.c -o myloader 

Run:

josh$ ./myloader 
in another thread 

Заметим, что myloader никоим образом не связан с PTHREAD, но PTHREAD функции загружаются и доступный во время выполнения через комплект.

+0

Поблагодарите jrodatus. Мне действительно интересно экспортировать символ из моего пакета, который будет напрямую указывать на адрес в dylib, с которым он связан. – Danra

+0

@ Danra, AFAIK, связанная с dylib, по определению означает, что код dylib на самом деле не содержится в комплекте, присутствуют только функции «dyld stub», которые перенаправляются во время выполнения. Адреса любых функций dylib, будь то puts(), printf() или pthread_create(), являются неопределенными во время компиляции, определяемые только dylinker во время выполнения. Например, даже вызов puts() из foo() фактически не ссылается на адрес в dylib, просто адрес функции-заглушки, которая вызывает dylinker, чтобы получить все, что имеет адрес puts(), в системе в этой среде выполнения (см. 'otool -tV'). – jrodatus

+0

@ Danra, ... Поэтому мне кажется, что лучше всего вы можете попросить экспортировать (из пакета) локальный dyld-адрес-заглушку, что и делает мой код (если я не ошибаюсь). Запуск 'nm' в любом скомпилированном двоичном файле будет перечислять функции-резидентные функции-dylib как« U »(undefined), так как их код НЕ присутствует во время компиляции, и, следовательно, их адреса символов не определены. Или, может быть, я просто не понимаю вас? – jrodatus