Russian Qt Forum
Ноябрь 01, 2024, 04:20
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Общие вопросы
>
Совместимлсть Qt dll
Страниц:
1
[
2
]
3
4
5
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Совместимлсть Qt dll (Прочитано 28502 раз)
Alex Custov
Джедай : наставник для всех
Offline
Сообщений: 2063
Re: Совместимлсть Qt dll
«
Ответ #15 :
Июнь 26, 2014, 16:05 »
Цитата: Igors от Июнь 26, 2014, 15:50
- это выглядит глупо и противоречит идее dll
идея dll - это dll в каком-либо системном каталоге, откуда её могут подгружать те кому надо, как Linux. В Windows всё немного по-другому. Если Qt каким-то образом установлен в системный каталог, то 10 Qt приложенгий могут загрузить Qt5Core из него, и скорее всего, что в памяти будет только одна копия dll. Случай же с dll, которая лежит рядом с exe - другой. Поэтому либо ОС обязана проверять сходность нашей dll со всеми теми, что уже загружены в памяти, либо просто игнорировать тот факт, что в памяти уже могут быть точно такие же dll и грузить ещё одну, нашу копию. Что на будет делать в реальности я не знаю, такой информации у меня нет, хотя я и склоняюсь к 10 копиям просто по логике.
«
Последнее редактирование: Июнь 26, 2014, 16:09 от Alex Custov
»
Записан
alex312
Хакер
Offline
Сообщений: 606
Re: Совместимлсть Qt dll
«
Ответ #16 :
Июнь 26, 2014, 19:35 »
Цитата: Igors от Июнь 26, 2014, 15:50
Хорошо, давайте так: на 1 машине 10 Qt приложений, каждое имеет Qt5Core.dll рядом с exe. Если все 10 приложений запущены - сколько копий Qt5Core.dll будет загружено в память? Все 10? Я не знаю "правельный ответ", но очень сомневаюсь что все 10 т.к.
За 10 не скажу, но 2 приложения у меня сейчас работают каждое со своей копией Qt5Core.dll .
Записан
Serr500
Гость
Re: Совместимлсть Qt dll
«
Ответ #17 :
Июнь 27, 2014, 12:26 »
Цитата: Igors от Июнь 26, 2014, 15:50
- выходит "всегда юзается та dll что рядом c exe - что-то слишком просто. Напр зачем тогда эта городушка
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682600%28v=vs.85%29.aspx
Эта "городушка" работает немного не так, как обычно думают. Если вы через LoadLibrary в коде грузите DLL с указанием абсолютного пути, то при наличии .local-файла абсолютный путь будет проигнорирован и поиск начнётся с каталога .exe-файла.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Совместимлсть Qt dll
«
Ответ #18 :
Июнь 27, 2014, 12:52 »
Цитата: Bepec от Июнь 26, 2014, 15:55
Думаю будет загружено 10 штук.
Почему это глупо, подскажите пожалуйста?
Пример: Qt dll-ки в памяти занимают... ну много, метров 30 (не проверял, может и больше). 10 запущенных Qt приложений - вполне реально. Расход физической памяти 300 метров (вместо 30). По нынешним временам не катастрофа, но, мягко говоря, "не по-хозяйски".
Цитата: alex312 от Июнь 26, 2014, 19:35
За 10 не скажу, но 2 приложения у меня сейчас работают каждое со своей копией Qt5Core.dll .
Подтверждаю для 3-х
Цитата: Serr500 от Июнь 27, 2014, 12:26
Эта "городушка" работает немного не так, как обычно думают. Если вы через LoadLibrary в коде грузите DLL с указанием абсолютного пути, то при наличии .local-файла абсолютный путь будет проигнорирован и поиск начнётся с каталога .exe-файла.
Т.е. предполагается такой сценарий: инсталлятор куда-то слил dll-ки и, возможно, прописал path. Неск приложений оттуда грузят. Теперь dll-ки обновилось, а одно из приложений это не устраивает. И вот тогда с помощью redirection его можно "подлечить". Хтозна-шо
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Совместимлсть Qt dll
«
Ответ #19 :
Июнь 27, 2014, 12:57 »
Да, к чему я все это спрашиваю: у меня 4 модуля, изначально в 1 фолдере, но один из них обычно интенсивно копируется в рамках одной машины, нередко 6-8 раз. Как лучше организовать dll-ки на Вындоуз?
Спасибо
Записан
Bepec
Гость
Re: Совместимлсть Qt dll
«
Ответ #20 :
Июнь 27, 2014, 13:16 »
Эмм...
А как оно копируется? модуль ваш? с dll или без?
Как вариант симлинки на ваши dll али же в system32 запихать.
Записан
Serr500
Гость
Re: Совместимлсть Qt dll
«
Ответ #21 :
Июнь 27, 2014, 14:04 »
Цитата: Igors от Июнь 27, 2014, 12:52
Т.е. предполагается такой сценарий: инсталлятор куда-то слил dll-ки и, возможно, прописал path. Неск приложений оттуда грузят. Теперь dll-ки обновилось, а одно из приложений это не устраивает. И вот тогда с помощью redirection его можно "подлечить". Хтозна-шо
Следствие недостаточно продуманной архитектуры первых версий Windows...
Потом придумали WinSxS...
Записан
OKTA
Гость
Re: Совместимлсть Qt dll
«
Ответ #22 :
Июнь 27, 2014, 14:22 »
Да копия у каждого приложения, копия!
Иначе что, сделал QLibrary::unload () и все, крах системы?
Если нужна только одна dll-ка, то берем системное API и нагло насилуем библиотеку какого-нибудь одного приложения
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Совместимлсть Qt dll
«
Ответ #23 :
Июнь 27, 2014, 17:44 »
Цитата: Bepec от Июнь 27, 2014, 13:16
Эмм...
А как оно копируется? модуль ваш? с dll или без?
Как вариант симлинки на ваши dll али же в system32 запихать.
Нет уж, в system32 ничего пихать не будем
Допустим простейший вариант: кладем все рядом с exe. Тогда придется вдаваться в не очень удобные объяснения типа "Вы ж все что начинается с "Q" тоже копируйте" + расход памяти.
Конечно копированием одного exe все равно не обойтись, поэтому пользователи уже приучены копировать фолдер Resources, это не вызовет никаких вопросов. Заметно лучше было бы слить dll-ки туда, но тогда нет никаких гарантий что там они найдутся первыми. Кстати пробовал подсунуть др Qt5Core.dll - он ее хватает и вякает что плохая.
А лучше всего было бы создать фолдер с именем DLL и туда все лить - но опять-таки, как обеспечить надежную "находимость"?
Цитата: OKTA от Июнь 27, 2014, 14:22
Да копия у каждого приложения, копия!
Иначе что, сделал QLibrary::unload () и все, крах системы?
unload уменьшает счетчик ссылок, неоднократно встречал это упоминание
Цитата: OKTA от Июнь 27, 2014, 14:22
Если нужна только одна dll-ка, то берем системное API и нагло насилуем библиотеку какого-нибудь одного приложения
Каким образом? Изложите план насилия
Записан
OKTA
Гость
Re: Совместимлсть Qt dll
«
Ответ #24 :
Июнь 27, 2014, 19:27 »
Ведется подсчет ссылок внутри процесса и выгрузится он из этого процесса, а не из памяти.
А вот статейка про то самое
http://www.codeproject.com/Tips/139349/Getting-the-address-of-a-function-in-a-DLL-loaded
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Совместимлсть Qt dll
«
Ответ #25 :
Июнь 28, 2014, 09:55 »
Цитата: OKTA от Июнь 27, 2014, 19:27
Ведется подсчет ссылок внутри процесса и выгрузится он из этого процесса, а не из памяти.
А вот статейка про то самое
http://www.codeproject.com/Tips/139349/Getting-the-address-of-a-function-in-a-DLL-loaded
Не вижу никакой связи этой статьи с данной темой
Ладно, подведем итоги. Я понял так:
- dll ищется на диске, правила поиска хорошо известны/описаны. Если найденная dll (именно этот файл, модуль) уже загружена (любым процессом, не только текущим), то она и используется (мапится в память процесса) и счетчик ссылок на нее увеличивается. Иначе dll грузится с диска.
В результате можно иметь сколько угодно одинаковых копий - напр для одинаковых dll файлов лежащих в разных местах рядом с разными exe. Выходит это гарантирует запуск. Чтобы обеспечить использование одной копии - надо что-то делать с path, чтобы находили один и тот же файл.
Если dll с нужным именем уже в памяти процесса - ну здравый смысл говорит что она и будет использована (хотя Вындоуз - хз). А "совместимость Qt dll" решается до боли просто: разными именами dll (напр Qt4Core.dll и Qt5Core.dll), никакого другого "идентификатора версии" они не имеют (нет его и в манифестах что в ресурсах).
Правильно ли я понял? Какие др мнения?
Спасибо
Записан
OKTA
Гость
Re: Совместимлсть Qt dll
«
Ответ #26 :
Июнь 30, 2014, 09:35 »
В статье как раз описано, как получить доступ к методам dll, загруженной в другой процесс....
Dll не берется из памяти, если такая же уже загружена... Она всегда берется с диска.. Почитайте ради интереса статейки.
http://www.rsdn.ru/?article/baseserv/InjectDll.xml
http://www.rsdn.ru/article/baseserv/apicallsintercepting.xml
Там описаны методы внедрения dll в память процесса из которых понятно, что каждый процесс (без внешнего вмешательства) берет библиотеку с диска, а не из памяти... Вы представьте в голове простейший вариант - если бы dll бралась из памяти (при условии, что какой-от процесс с такой библиотекой уже запущен), то достаточно было бы написать приложение одно, которое просто загружает все нужные хакеру dll и запускать его перед стартом всех остальных интересующих процессов... Такой глупости не может быть, хотя она и была... вот кусок из одной из статей..
Цитировать
Так как перехват практически всегда связан с модификацией памяти (либо кода перехватываемой функции, либо таблиц импорта/экспорта), то для его осуществления необходимо учитывать особенности архитектуры памяти WinNT и Win9X.
Каждому процессу (начиная с Windows 95) выделяется собственное виртуальное адресное пространство. Для 32-разрядных процессов его размер составляет 4 Гб. Это адресное пространство разбивается на разделы, функциональное назначение и свойства которых довольно сильно отличаются у семейств ОС WinNT и Win9Х.
Адресное пространство любого процесса в Win9Х можно разделить на три раздела:
Младшие два гигабайта (00400000-7FFFFFFF) – код и данные пользовательского режима (в диапазоне 00000000-003FFFFF расположены разделы для выявления нулевых указателей и для совместимости с программами DOS и Win16);
Третий гигабайт – для общих файлов, проецируемых в память (MMF), и системных DLL.
Четвёртый гигабайт – для кода и данных режима ядра (здесь располагается ядро операционной системы и драйверы).
Старшие два гигабайта являются общими для всех процессов. Основные системные DLL – kernel32.dll, advAPI32.dll, user32.dll и GDI32.dll загружаются в третий гигабайт. По этой причине эти четыре библиотеки доступны всем процессам в системе. Поскольку этот гигабайт общий, они существуют во всех процессах по одним и тем же адресам. Из соображений безопасности Microsoft запретила запись в область, куда они загружаются. Если же запись туда всё же произвести (а это возможно из режима ядра или недокументированными методами), то изменения произойдут во всех процессах одновременно.
В WinNT общих разделов у процессов нет, хотя системные библиотеки по-прежнему во всех процессах загружаются по одинаковым адресам (но теперь уже в область кода и данных пользовательского режима). Запись в эту область разрешена, но у образов системных библиотек в памяти стоит атрибут «копирование при записи» (copy-on-write). По этой причине попытка записи, например, в образ kernel32.dll приведёт к появлению у процесса своей копии изменённой страницы kernel32.dll, а на остальных процессах это никак не отразится.
Все эти различия существенно влияют на способы реализации перехвата функций, расположенных в системных DLL.
Перехваты можно разделить на два типа: локальные (перехват в пределах одного процесса) и глобальные (в масштабах всей системы).
Записан
OKTA
Гость
Re: Совместимлсть Qt dll
«
Ответ #27 :
Июнь 30, 2014, 09:55 »
А еще есть такая книжечка "Windows для профессионалов". Вот выдержки из нее
Цитировать
Выполнение EXE-модуля
При запуске EXE-файла загрузчик операционной системы создает для его процесса
виртуальное адресное пространство и проецирует на него исполняемый модуль. Далее загрузчик анализирует раздел импорта и пытается спроецировать все необходимые DLL на адресное пространство процесса.
Поскольку в разделе импорта указано только имя DLL (без пути), загрузчику приходится самому искать ее на дисковых устройствах в компьютере пользователя. Поиск DLL осуществляется в следующей последовательности.
1. Каталог, содержащий EXE-файл.
2. Текущий каталог процесса.
3. Системный каталог Windows.
4. Основной каталог Windows.
5. Каталоги, указанные в переменной окружения PATH.
Учтите, что на процесс поиска библиотек могут повлиять и другие факторы
(см. главу 20). Проецируя DLL-модули на адресное пространство, загрузчик проверяет в каждом из них раздел импорта. Если у DLL есть раздел импорта (что обычно и
бывает), загрузчик проецирует следующий DLL-модуль. При этом загрузчик ведет учет
загружаемых DLL и проецирует их только один раз, даже если загрузки этих DLL требуют и другие модули.
Если найти файл DLL не удается, загрузчик выводит одно из двух сообщений
А вот про счетчики еще из той же книжечки:
Цитировать
На самом деле LoadLibrary и LoadLibraryEx лишь увеличивают счетчик числа пользователей указанной библиотеки, а FreeLibrary и FreeLibraryAndExitThread его уменьшают. Так, при первом вызове LoadLibrary для загрузки DLL система проецирует образ DLL-файла на адресное пространство вызывающего процесса и присваивает единицу счетчику числа пользователей этой DLL. Если поток того же процесса вызывает
LoadLibrary для той же DLL еще раз, DLL больше не проецируется; система просто
увеличивает счетчик числа ее пользователей вот и все.
Чтобы выгрузить DLL из адресного пространства процесса, FreeLibrary придется
теперь вызывать дважды: первый вызов уменьшит счетчик до 1, второй до 0. Обнаружив, что счетчик числа пользователей DLL обнулен, система отключит ее. После
этого попытка вызова какой-либо функции из данной DLL приведет к нарушению
доступа, так как код по указанному адресу уже не отображается на адресное пространство процесса.
Система поддерживает в каждом процессе свой счетчик DLL, т. е. если поток
процесса А вызывает приведенную ниже функцию, а затем тот же вызов делает поток
в процессе В, то MyLib.dll проецируется на адресное пространство обоих процессов,
а счетчики числа пользователей DLL в каждом из них приравниваются 1.
HINSTANCE hinstDll = LoadLibrary("MyLib.dll");
Если же поток процесса В вызовет далее:
FreeLibrary(hinstDll);
счетчик числа пользователей DLL в процессе В обнулится, что приведет к отключению DLL от адресного пространства процесса В. Но проекция DLL на адресное пространство процесса А не затрагивается, и счетчик числа пользователей DLL в нем
остается прежним.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Совместимлсть Qt dll
«
Ответ #28 :
Июнь 30, 2014, 11:31 »
Цитата: OKTA от Июнь 30, 2014, 09:35
Dll не берется из памяти, если такая же уже загружена... Она всегда берется с диска..
MSDN пишет
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx
Цитировать
If a DLL with the same module name is already loaded in memory, the system checks only for redirection and a manifest before resolving to the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
Здесь важно "same module name" - это должен быть "именно тот файл" (а не др хоть и идентичный)
Проверим на той же Qt5Core.dll запустив 2 Qt приложения. Утилита listDLLs.exe показывает
Цитировать
Test1.exe pid: 3768
Command line: "C:\QT_Training\Test1\Win32\Debug\Test1.exe"
Base Size Path
0x0000000050080000 0x7ec000 C:\Qt\5.2.0\msvc2012\bin\Qt5Cored.dll
windowflags.exe pid: 4984
Command line: "C:\Qt\5.2.0\msvc2012\examples\widgets\widgets\windowflags\debug\windowflags.exe"
Base Size Path
0x0000000050080000 0x7ec000 C:\Qt\5.2.0\msvc2012\bin\Qt5Cored.dll
Base одинаковый, в памяти одна копия. Положите dll рядлм с каждым exe - будут 2 копии.
Цитата: OKTA от Июнь 30, 2014, 09:35
Почитайте ради интереса статейки.
А Вы их сами внимательно читали?
Давайте попробуем вместе
Цитировать
Система поддерживает в каждом процессе свой счетчик DLL, т. е. если поток
процесса А вызывает приведенную ниже функцию, а затем тот же вызов делает поток
в процессе В, то MyLib.dll проецируется на адресное пространство обоих процессов,
а счетчики числа пользователей DLL в каждом из них приравниваются 1.
Нема квешнзов, dll используется ОДНА, "проекций" может быть сколько угодно
Цитировать
Если же поток процесса В вызовет далее:
FreeLibrary(hinstDll);
счетчик числа пользователей DLL в процессе В обнулится, что приведет к отключению DLL от адресного пространства процесса В. Но проекция DLL на адресное пространство процесса А не затрагивается, и счетчик числа пользователей DLL в нем остается прежним.
Тоже все ясно, dll в памяти пока ею пользуется хоть один процесс
Записан
OKTA
Гость
Re: Совместимлсть Qt dll
«
Ответ #29 :
Июнь 30, 2014, 12:23 »
MSDN говорит о загрузке библиотеки внутри одного процесса, а не среди нескольких.
Цитировать
Здесь важно "same module name" - это должен быть "именно тот файл" (а не др хоть и идентичный)
- это просто имя файла библиотеки и ничего больше. Соответственно, следуя Вашей логике, система Windows не может содержать в памяти несколько библиотек с одинаковыми именами...
И почему это приложение отказывается стартовать, если не видит библиотеки на диске, хоть и приложение с такой же библиотекой будет одновременно работать?
Записан
Страниц:
1
[
2
]
3
4
5
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...