2014-10-11 12 views
8

Chcę umieścić dwie aliasingowane zmienne w bibliotece, aby kod aplikacji mógł używać obu nazw. Ale uważam, że można to zrobić w bibliotece statycznej, ale nie w bibliotece współdzielonej. Oto mój eksperyment. Zrobiłem to na maszynie X86 Linux z kompilatorem gcc.Jak uzyskać aliasing zmiennych w bibliotekach współdzielonych?

test.c - kod aplikacji

#include <stdio.h> 
extern int myfunc(int, int); 
extern int myglob; 
extern int myglob_; 

int main(int argc, const char* argv[]) 
{ 
    printf("&myglob = %p\n", &myglob); 
    printf("&myglob_ = %p\n", &myglob_); 
    myglob = 1234; 
    printf("myglob = %d\n", myglob); 
    printf("myglob_ = %d\n", myglob_); 

    return myfunc(argc, argc); 
} 

my.c - kod biblioteki

int myglob = 42; 
extern int myglob_ __attribute__ ((alias("myglob"))); 
int myfunc(int a, int b) 
{ 
    myglob += a; 
    return b + myglob; 
} 

budowy i uruchomienia z biblioteką statyczną. Możemy zobaczyć, że myglob i myglob_ są rzeczywiście aliasingowane.

gcc -c my.c 
ar rsc libmy.a my.o 
gcc -o test test.c -L. -lmy 
./test 
&myglob = 0x601040 
&myglob_ = 0x601040 
myglob = 1234 
myglob_ = 1234 

Tworzenie i uruchamianie z udostępnioną biblioteką. Możemy zobaczyć, że myglob i myglob_ wskazują na różne adresy i zasadniczo są to dwie różne zmienne.

Dlaczego symbole alikwotowe nie działają w bibliotece współdzielonej? Jak to naprawić? Dzięki.

============= Kontynuacja ===============

Próbowałem zbudować wykonywalny niezależne od pozycji przy użyciu „gcc -o test test.c -L. -lmy -fPIC ". Dzięki temu, myglob i myglob_ są rzeczywiście aliasowane z biblioteką współdzieloną. Jednak takie podejście nie działa w tle problemu, który wywołał pytanie. Wymieniam problem i powód, dla którego go potrzebuję. (Zauważ, że muszę używać F77 wspólne bloki w moim projekcie) Plik

Fortran nagłówek

! myf.h 
common /myblock/ myglob 
save myblock 

Init rutyna w Fortran

! initf.f90 
subroutine initf() 
    integer myglob 
    common /myblock/ myglob 
    call initc(myglob) 
end subroutine 

Init rutyna w C

// initc.c 
#include <stdio.h> 
extern void initf_(); 
void init() { initf_(); } 
extern void init_() __attribute__((alias("init"))); 
void initc_(int *pmyglob) { printf("&myglob in library = %p\n", pmyglob); } 

Opakowanie biblioteki Fortran w C

// my.c 
#include <stdio.h> 
extern void myfunc(int *pmyglob) 
{ 
    printf("&myglob in app  = %p\n", pmyglob); 
    // May call a Fortran subroutine. That's why myfunc() is a wrapper 
} 
extern void myfunc_(int *) __attribute__ ((alias("myfunc"))); 
typedef struct myblock_t_ { 
    int idx; 
} myblock_t; 
myblock_t myblock __attribute__((aligned(16))) = {0}; 
extern myblock_t myblock_ __attribute__((alias("myblock"))); 

Zastosowanie w Fortran

! test.f90 
program main 
    include 'myf.h' 
    call init(); 
    call myfunc(myglob); 
end program 

Budowanie wspólnej libmy.so biblioteki i używać go

gfortran -fPIC -c initf.f90 
gcc -fPIC -c initc.c 
gcc -fPIC -c my.c 
gcc -fPIC -shared -o libmy.so initf.o initc.o my.o 
gfortran -fPIC -o test test.f90 -L. -lmy 
./test 
&myglob in library = 0x601070 
&myglob in app  = 0x601070 

Załóżmy, że chcemy biblioteka być przenośne, a aplikacja jest skompilowany przez innego kompilatora Fortran z inną nazwą - konwencja mangling (używam gfortran - podświetlając to naśladując)

// libmy.so is built as same as above 
... 
gfortran -fPIC -fno-underscoring -o test test.f90 -L. -lmy 
./test 
&myglob in library = 0x7fb3c19d9060 
&myglob in app  = 0x601070 

Jakieś sugestie? Dzięki.

+1

Jakie jest pozostałe pytanie? Odkryłeś '-fPIC' i wszystko działa zgodnie z przeznaczeniem. Co zostało? –

+0

Jak widać w sekcji kontrolnej, to nie działa dla hybrydowego kodu Fortran/C. –

+0

Pomyślałem, że udało ci się przekonać twoich linkerów, żeby zgodzili się na mylące nazwy? –

Odpowiedz

2

Dzieje się tak z powodu przeniesienia kopii. Przeczytaj o nich here.

readelf -Wr test | grep myglob 
0000000000601028 0000000600000005 R_X86_64_COPY 0000000000601028 myglob + 0 
0000000000601030 0000000900000005 R_X86_64_COPY 0000000000601030 myglob_ + 0 
+0

Dzięki. Znalazłem, jeśli skompilowałem plik wykonywalny niezależny od pozycji, tj. Używając "gcc -o test test.c -L. -lmy -fPIC", to nawet z biblioteką współdzieloną myglob i myglob_ są aliasingowane. Jest to akceptowalne, ale nie idealne. Ale kiedy zastosowałem to podejście do problemu tła w moim projekcie, nie zadziałało. Dam nowy post. –

Powiązane problemy