gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:04:04 26 4
gpt4 key购买 nike

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

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);
}

my.c -- 库代码

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

使用静态库构建并运行。我们可以看到 myglob 和 myglob_ 确实存在别名。

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_ 指向不同的地址,基本上是两个不同的变量。

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 test.c -L. -lmy -fPIC”构建一个与位置无关的可执行文件。有了这个,myglob 和 myglob_ 确实是共享库的别名。但是,这种方法不适用于产生问题的背景问题。我列出了问题以及我需要它的原因。 (注意我的项目中必须使用F77公共(public) block )

一个 Fortran 头文件

! myf.h
common /myblock/ myglob
save myblock

Fortran 中的初始化例程

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

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); }

C 中的 Fortran 库包装器

// 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")));

在 Fortran 中的应用

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

构建共享库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-underscoring 来模拟)

// 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

有什么建议吗?谢谢。

最佳答案

这是由于副本重定位而发生的。了解它们 here .

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

关于c - 如何在共享库中使用别名变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26315641/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com