C 如何在共享库中使用别名变量?

C 如何在共享库中使用别名变量?,c,linker,fortran,alias,loader,C,Linker,Fortran,Alias,Loader,我想在一个库中放入两个别名变量,以便应用程序代码可以使用任意一个名称。但我发现它可以在静态库中完成,但不能在共享库中完成。这是我的实验。我用gcc编译器在x86linux机器上实现了这一点 test.c——应用程序代码 #include <stdio.h> extern int myfunc(int, int); extern int myglob; extern int myglob_; int main(int argc, const char* argv[]) {

我想在一个库中放入两个别名变量,以便应用程序代码可以使用任意一个名称。但我发现它可以在静态库中完成,但不能在共享库中完成。这是我的实验。我用gcc编译器在x86linux机器上实现了这一点

test.c——应用程序代码

#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);
}
使用静态库构建并运行。我们可以看到myglob和myglob_u确实是别名

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
使用共享库构建并运行。我们可以看到myglob和myglob_u指向不同的地址,基本上是两个不同的变量

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
那么,为什么别名符号在共享库中不起作用呢?如何修复它?谢谢

==================后续行动===============

我尝试使用“gcc-o test.c-L-lmy-fPIC”构建一个位置独立的可执行文件。有了这个,, myglob和myglob_u确实与共享库有别名。然而,这种方法在产生问题的背景问题中不起作用。我列出了问题以及我需要它的原因。(请注意,我必须在项目中使用F77公共块)

Fortran头文件

! myf.h
common /myblock/ myglob
save myblock
Fortran中的初始化例程

! initf.f90
subroutine initf()
    integer myglob
    common /myblock/  myglob
    call initc(myglob)
end subroutine
! test.f90
program main
    include 'myf.h'
    call init();
    call myfunc(myglob);
end program
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); }
构建一个共享库libmy.so并使用它

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
假设我们希望库是可移植的,并且应用程序由另一个Fortran编译器使用不同的名称混乱约定编译(我使用gfortran--fno下划线来模拟这一点)


有什么建议吗?谢谢。

发生这种情况是因为拷贝重新定位。了解他们


谢谢我发现,如果我构建一个独立于位置的可执行文件,即使用“gcc-o test test.c-L-lmy-fPIC”,那么即使使用共享库,myglob和myglob_2;也会有别名。这是可以接受的,但并不完美。但是当我在我的项目中将这种方法应用于背景问题时,它不起作用。我将发布一个新帖子。剩下的问题是什么?您已经发现了
-fPIC
,一切正常。剩下的是什么?正如在后续部分中所看到的,它不适用于Fortran/C混合代码。我认为您已经解决了需要让您的链接器就名称混乱达成一致意见的问题?我想要一种能够处理两种名称混乱约定的方法,即使库可移植。
! test.f90
program main
    include 'myf.h'
    call init();
    call myfunc(myglob);
end program
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
// 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
 readelf -Wr test | grep myglob
0000000000601028  0000000600000005 R_X86_64_COPY  0000000000601028 myglob + 0
0000000000601030  0000000900000005 R_X86_64_COPY  0000000000601030 myglob_ + 0