我制作了一段代码,它包含在一个动态库 ( lib.c
) 和一个主可执行文件 ( main.c
) 中。在这两个文件中,我定义了一个名为: 的全局变量int global
。不是很聪明,但这不是问题。
当我编译动态库时,该-fPIC
选项似乎是强制性的:
gcc lib.c -fPIC -shared -o lib.so
否则我得到:
/usr/bin/ld: /tmp/ccpUvIPj.o: relocation R_X86_64_32 against '.rodata' can not be used when making a shared object; recompile with -fPIC
当我编译可执行文件时,它不是。
gcc main.c -fPIC -ldl
gcc main.c -ldl
两者都有效,但有不同的行为我无法解释,你可以吗?:
使用 -fPIC,main.c 中的 global 和 lib.c 中的 global 是相同的变量:
global main: 23 (0x601050)
global lib: 23 (0x601050)
如果没有 -fPIC,lib.c 中的全局与 main.c 中的全局无关:
global main: 23 (0x601048)
global lib: 0 (0x7f7742e64028)
这是来源:
库文件
#include <stdio.h>
#include <stdlib.h>
int global;
int f_one() {
printf("global lib: %d (%p)\n", global, &global);
return EXIT_SUCCESS;
}
主程序
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void * handle;
int global;
int main() {
int q = 7;
int (* f_one_p)(int a) = NULL;
global = 23;
handle = dlopen("./lib.so", RTLD_NOW);
if (handle == 0) {
return EXIT_FAILURE;
}
f_one_p = dlsym(handle, "f_one");
printf("global main: %d (%p)\n", global, &global);
f_one_p(q);
return EXIT_SUCCESS;
}
gcc --version: gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
uname -a: Linux xxx 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:02:55 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
编辑:在 SUN/sparc 和 x86/Linux 架构下测试的代码具有相同类型的意外共享全局变量(使用 -fPIC)。