Я создал фрагмент кода, который состоит из динамической библиотеки (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, global в main.c и global в lib.c - это одни и те же переменные:
global main: 23 (0x601050)
global lib: 23 (0x601050)
без -fPIC, global в lib.c не коррелирует с globalв main.c:
global main: 23 (0x601048)
global lib: 0 (0x7f7742e64028)
Вот источник:
lib.c
#include <stdio.h>
#include <stdlib.h>
int global;
int f_one() {
printf("global lib: %d (%p)\n", global, &global);
return EXIT_SUCCESS;
}
main.c
#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 пт 29 июля 19:02:55UTC 2011 x86_64 x86_64 x86_64 GNU / Linux
edit : код, протестированный в архитектурах SUN / sparc и x86 / Linux с такими же неожиданными общими глобальными переменными (с -fPIC).