И статические переменные, и глобальные переменные показывают разные адреса в динамической библиотеке и статической библиотеке в Linux?

Я сталкивался на CentOS 6.5. Как я искал в Интернете, статическая переменная ведет себя по-разному в Windows и в Linux при использовании динамической библиотеки. Таким образом, Windows вызовет дублирование переменных, а Linux — нет, например:
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

Однако, когда я написал небольшую программу для проверки этого, я обнаружил, что Linux также вызывает дублирование. Вот моя маленькая программа, включающая четыре файла:

(1) А.ч

#ifndef A_H
#define A_H
#include <cstdio>
static int b;
extern "C" class A {
public:
int mem;
A() {
printf("A's address: %p\n", this);
printf("B's address: %p\n", &b);
}
void print() {
printf("%p: %d\n", this, mem);
}
~A() {
printf("DELETE A!!!!! %p\n", this);
}
};
extern A a;
#endif

(2) A.cpp

#include "A.h"A a;

(3) d.cpp

#include "A.h"extern "C" void exec() {
a.print();
}

(4) main.cpp

#include "A.h"#include <dlfcn.h>
typedef void (*fptr) ();
int main() {
a.mem = 22;
a.print();
void *handle;
handle = dlopen("d.so", RTLD_LAZY);
fptr exec = reinterpret_cast<fptr>(dlsym(handle, "exec"));
(*exec)();
dlclose(handle);
return 0;
}

Вот как я компилирую и запускаю свою программу:

g++ d.cpp A.cpp -shared -rdynamic -o d.so -ldl -I. -fPIC -g -std=c++1y
g++ main.cpp A.cpp -ldl -I. -g -std=c++1y
./a.out

Как динамическая часть d.cpp и статическая часть main.cpp использовать переменные a а также b объявлено в A.cpp а также A.h, И вот результат программы на моей машине:

A's address: 0x600f8c
B's address: 0x600f90
0x600f8c: 22
A's address: 0x7fb8fe859e4c
B's address: 0x7fb8fe859e50
0x7fb8fe859e4c: 0
DELETE A!!!!! 0x7fb8fe859e4c
DELETE A!!!!! 0x600f8c

Это меня очень удивляет, потому что адреса глобальной переменной a и статическая переменная b должно быть одинаковым в динамической части и статической части. И кажется, что модификация на a в статической части не влияет на a в динамической части. Кто-нибудь, пожалуйста, ответьте на мой вопрос или помогите найти ошибки в программе (если есть)?

Кстати, если честно, в другом проекте, над которым я работаю, я обнаружил, что адреса глобальных переменных одинаковы в динамической и статической библиотеках. Но этот проект слишком большой, и я не могу предоставить небольшую программу для воспроизведения поведения.

Большое спасибо !

1

Решение

Первая команда, которую вы показали, создает общий объект d.so, Исходя из контекста вашего вопроса, я полагаю, что вы также намеревались связаться с d.so, но ваша вторая команда, кажется, пропустил эту часть. Я предполагаю, что это опечатка, так как это единственное объяснение вывода программы, которую вы показали — что A.cpp связан как напрямую, так и встроен в ваш d.so библиотека.

Учитывая это, цитата из статьи, на которую вы ссылались:

Подпрограммы объектного кода, используемые обоими, не должны дублироваться в каждом.
Это особенно верно для кода, который использует статические переменные, такие как
синглтон классы. Статическая переменная является глобальной и поэтому может быть только
представлены один раз. Включение его дважды даст неожиданные результаты.

Но это именно то правило, которое вы, кажется, нарушаете, вы представляете статически ограниченный экземпляр A класс в два раза, в вашем d.soи в вашем основном приложении исполняемый файл.

Таким образом, это, кажется, указанный результат: «неожиданные результаты».

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector