Ich möchte zwei Alias-Variablen in eine Bibliothek einfügen, so dass der Anwendungscode beide Namen verwenden kann. Aber ich finde, dass es in einer statischen Bibliothek, aber nicht in einer gemeinsam genutzten Bibliothek getan werden kann. Hier ist mein Experiment. Ich habe es auf einem X86 Linux-Rechner mit GCC-Compiler gemacht.Wie haben Sie Alias-Variablen in Shared Libraries?
test.c - der Anwendungscode
#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 - der Bibliothekscode
int myglob = 42;
extern int myglob_ __attribute__ ((alias("myglob")));
int myfunc(int a, int b)
{
myglob += a;
return b + myglob;
}
Aufbau und Betrieb mit statischer Bibliothek. Wir können sehen, myglob und myglob_ sind in der Tat Alias.
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
Erstellen und Ausführen mit einer gemeinsam genutzten Bibliothek. Wir können myglob und myglob_ auf verschiedene Adressen zeigen und sind im Grunde zwei verschiedene Variablen.
gcc -fPIC -c my.c
gcc -shared -o libmy.so my.o
gcc -o test test.c -L. -lmy
./test
&myglob = 0x601048
&myglob_ = 0x601050
myglob = 1234
myglob_ = 42
Also, warum Alias-Symbole nicht in der gemeinsamen Bibliothek arbeiten? Wie man es repariert? Vielen Dank.
============= Follow-up ===============
Ich habe versucht, eine positionsunabhängige Executable mit „gcc zu bauen -o test test.c -L. -lmy -fPIC ". Damit sind myglob und myglob_ tatsächlich Aliasing mit der gemeinsam genutzten Bibliothek. Dieser Ansatz funktioniert jedoch nicht in dem Hintergrundproblem, das die Frage hervorgebracht hat. Ich liste das Problem und den Grund auf, warum ich es brauche. (Beachten Sie, dass ich F77 gemeinsame Blöcke in meinem Projekt verwenden)
Eine Fortran-Header-Datei
! myf.h
common /myblock/ myglob
save myblock
Init-Routine in Fortran
! initf.f90
subroutine initf()
integer myglob
common /myblock/ myglob
call initc(myglob)
end subroutine
Init-Routine in 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); }
Fortran Bibliothekswrapper in 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")));
Anwendung in Fortran
! test.f90
program main
include 'myf.h'
call init();
call myfunc(myglob);
end program
Erstellen Sie eine gemeinsame Bibliothek libmy.so und es verwenden,
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
Angenommen wir die Bibliothek wollen tragbar sein, und die Anwendung wird von einem anderen Fortran-Compiler kompiliert mit einem anderen Namen Mangling Konvention (ich benutze gfortran - fno-Unterstreichung, um das nachzuahmen)
// 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
Irgendwelche Vorschläge? Vielen Dank.
Was ist die verbleibende Frage? Du hast '-fPIC' entdeckt und alles funktioniert wie beabsichtigt. Was ist übrig? –
Wie im folgenden Abschnitt zu sehen, funktioniert es nicht für Fortran/C-Hybridcode. –
Ich dachte, du hast herausgefunden, dass du deine Linker dazu bringen musst, dem Namen Mangling zuzustimmen? –