Название: Проблема с доступом к static переменной Отправлено: jasf от Ноябрь 20, 2009, 02:08 Здравствуйте. Столкнулся с большой проблемой. За весь вечер ничего не нашёл (в том числе и в гугле).
Имеется 1 статическая, 1 динамическая (1 extern "C" функция ) дллка, и 1 ехешник. ехешник и дин. дллка слинкованны со статической дллкой. в стат. дллке есть переменная int var; *.h extern int var; *.cpp int var = 1; void QMyApplication::QMyApplication():QApplication(){var=2;} т.е. как видно, класс приложения находится в стат. дллке, exeшник при запуске создаёт экземпляр данного класса, и var получает значение 2. потом подгружается дин. дллка, и что мы видим? var в этой дллке имеет значение 1! >:( :'(. Адрес переменной var в дин. дллке не совпадает с адресом из .exeшника. Т.е. явно видно, что дин.дллка заалоцировала и сиинициализирова свой участок памяти под var, когда как данная переменная уже есть в области данных процесса. Взлянув в QCoreApplication::self, вижу - что адрес этой переменной, при доступе что из .ехе, что из дин. дллки не меняется. адрес же всех статических переменных в моей стат. дллке - изменён. покопав, так же заметил, что классы Qt (типа QWidget) задекларированы как __declspec(dllimport), что несколько удивило (Visual studio компилятор выдаёт ошибку при попытке повторения подвига). помогите разобраться пожалуйста. P.S. задекларировать эту var пытался очень по разному.. не помогло. Название: Re: Проблема с доступом к static переменной Отправлено: break от Ноябрь 20, 2009, 04:55 она объявлена как
Код: int var = 1; Код: static int var = 1; Название: Re: Проблема с доступом к static переменной Отправлено: SASA от Ноябрь 20, 2009, 09:58 В этом и есть отличие динамической линковки от статической. При статической линковке, каждый создаёт по экземпляру данных и кода, а при динамической все пользуются общими. Т.е. если вашу статическую либку подключат три длл, то будает созданно три переменных var.
Название: Re: Проблема с доступом к static переменной Отправлено: jasf от Ноябрь 20, 2009, 10:00 ещё раз повторюсь, что как бы я её не объявлял.. эффекта ноль. все глобальные переменные, объявленные в стат. дллке изменяют свой адрес и реинициализируются в дин. дллке.
объявлена полностью по аналогии со static QCoreApplication* self;, т.е. *.h class MY_EXPORT_C QMYApplication : public QApplication { ... static QMYApplication * mySelf; }; *.cpp QMYApplication * QMYApplication ::mySelf = 0; #define MY_EXPORT_C __declspec(dllexport) нет я конечно могу в QMyApplication создать хранилище, и через него реализовать глобальные переменные, но это ж ахтунг! сколько пользуюсь ими (глобальными переменными) на других платформах - никогда ничего подобного не встречал.. Название: Re: Проблема с доступом к static переменной Отправлено: jasf от Ноябрь 20, 2009, 10:02 В этом и есть отличие динамической линковки от статической. При статической линковке, каждый создаёт по экземпляру данных и кода, а при динамической все пользуются общими. Т.е. если вашу статическую либку подключат три длл, то будает созданно три переменных var. тогда как сделано так, что даже если я подключаю дин. дллку, у QCoreApplication::self адрес остаётся неизменным? думается мне, что проблема в каких-то настройках компоновщика.. P.S. проект стат. дллки создан через визард. Всё по умолчанию. Название: Re: Проблема с доступом к static переменной Отправлено: SASA от Ноябрь 20, 2009, 10:13 тогда как сделано так, что даже если я подключаю дин. дллку, у QCoreApplication::self адрес остаётся неизменным? ответ:Код: дин. дллку Название: Re: Проблема с доступом к static переменной Отправлено: jasf от Ноябрь 20, 2009, 10:17 тогда как сделано так, что даже если я подключаю дин. дллку, у QCoreApplication::self адрес остаётся неизменным? ответ:Код: дин. дллку не понимаю. У меня есть в стат. дллке класс class MY_EXPORT_C QMYApplication : public QApplication : public QCoreApplication экзэмпляр создаётся в .ехешнике. В нём есть стат. переменная QCoreApplication::self. так вот когда я подключаю дин. дллку (через QLibrary), адрес QCoreApplication::self не изменяется, а адрес QMyApplication::mySelf изменяется. При этом например под Symbianом никогда подобного эффекта не было. Если я задекларировал mySelf в статик. длл, тогда могу из любого подключаемого модуля обращаться к этой переменной и у неё адрес изменяться не будет. Название: Re: Проблема с доступом к static переменной Отправлено: kuzulis от Ноябрь 20, 2009, 11:03 Цитировать не понимаю. У меня есть в стат. дллке статических дллок не бывает!Название: Re: Проблема с доступом к static переменной Отправлено: Igors от Ноябрь 20, 2009, 11:27 Тема интересная но трудно понять. Вы бы объяснили так
Код: // static lib Код: // dll Код: // exe А то путаница полная где кто Название: Re: Проблема с доступом к static переменной Отправлено: jasf от Ноябрь 20, 2009, 12:38 exe.exe и dynamic.dll слинкованы со static.dll
static.dll Код: // static dll dynamic.dll Код: // dynamic dll exe.exe Код: /////////////////////////////////////////////////// выход: in exe: &MyClass::self= 40a008 MyClass::self= 3eece0 in dll pself: &MyClass::self= 4c6048 MyClass::self= abcdef Название: Re: Проблема с доступом к static переменной Отправлено: jasf от Ноябрь 20, 2009, 13:12 Прошу прощения, разобрался. Помогло сделать static.dll - динамической. т.е. не shared_lib. Ошибка возникла из-за опыта работы с symbianом. Там shared lib является dllкой, и обращаться к функциям shared lib можно лишь при наличии .lib файла. Ну и такого поведения, как под windows (относительно памяти) - нет.
Название: Re: Проблема с доступом к static переменной Отправлено: Igors от Ноябрь 20, 2009, 13:48 Ну вот, другое дело, все ясно
in exe: По-моему, это правильный и ожидаемый результат. Если Вы линковали статически, то у Вас и есть 2 MyClass - один в exe, другой в dll и они просто 2 разных, никак не связаны и MyClass::self у каждого свой. Для того что в exe Вы создали экземпляр, его self заполнился. Но для того что в dll Вы экземпляр не создавали - ну он и имеет "abcdef". Если планируете общий MyClass - в dll его (как Вы и сделали) &MyClass::self= 40a008 MyClass::self= 3eece0 in dll pself: &MyClass::self= 4c6048 MyClass::self= abcdef |