Russian Qt Forum

Qt => Общие вопросы => Тема начата: Igors от Июнь 24, 2014, 15:41



Название: Совместимлсть Qt dll
Отправлено: Igors от Июнь 24, 2014, 15:41
Добрый день

Простой ответ неоднократно звучал, типа "плагин откомпиленный с Qt 4 не будет работать с Qt 5". Хорошо, верю, но многое остается неясным. Значит, пятерка с пятеркой - все норм, говорилось что "они имеют одинаковое ABI". А как в этом убедиться? Где/как посмотреть это самое ABI? В гугле ничего такого не наблюдаю.

И более важно: как быть если у меня кастомная сборка? Давеча обнаружил что либа OpenGL меня не устраивает (в том виде как скачал). Ладно, пересобрал как мне надо. Но теперь мне надо как-то обеспечить чтобы грузилась именно моя Qt5OpenGL.dll. Конечно я положу ее рядом с exe, но это ничего не гарантирует - если "подходящая" dll уже в памяти - ее и подсунут, на диске ничего искать не будут.

Просветите
Спасибо



Название: Re: Совместимлсть Qt dll
Отправлено: Alex Custov от Июнь 24, 2014, 15:53
А как в этом убедиться?

Это их заявленная возможность - совместимость снизу вверх.

Конечно я положу ее рядом с exe, но это ничего не гарантирует - если "подходящая" dll уже в памяти - ее и подсунут, на диске ничего искать не будут.

Твоя dll и та что в памяти - разные dll, следовательно ничего не подсунут (и кстати в какой ОС такой алгоритм?).


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 24, 2014, 18:12
Это их заявленная возможность - совместимость снизу вверх.
Верю, но как пощупать?

Твоя dll и та что в памяти - разные dll, следовательно ничего не подсунут (и кстати в какой ОС такой алгоритм?).
Да хотя бы в Вашей, напр MSDN пишет
Цитировать
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.


Название: Re: Совместимлсть Qt dll
Отправлено: mitrich от Июнь 25, 2014, 00:19
это ничего не гарантирует - если "подходящая" dll уже в памяти - ее и подсунут, на диске ничего искать не будут.
Гарантирует. Не подсунут.
Цитировать
If a DLL with the same module name is already loaded in memory, the system uses the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
Это если она уже загружена в адресное пространство твоего процесса, т.е., твоим приложением (ну, или вирусом каким-нибудь, который свой код таким образом подгружает :) ). То, что загружают другие приложения, твоего совершенно не касается.


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 25, 2014, 09:30
Это если она уже загружена в адресное пространство твоего процесса, т.е., твоим приложением (ну, или вирусом каким-нибудь, который свой код таким образом подгружает :) ). То, что загружают другие приложения, твоего совершенно не касается.
Допустим есть 2 (или более) Qt приложения и каждый положил Qt5Core.dll рядом с exe. По-Вашему выходит а памяти будут 2 копии этой dll - ну если "не касается". В это слабо верится, что за dll если каждый процесс ее опять загружает? Естественно предположить что в памяти будет одна, отмапленная в адресное пр-во каждого процесса.


Название: Re: Совместимлсть Qt dll
Отправлено: navrocky от Июнь 25, 2014, 09:43
Допустим есть 2 (или более) Qt приложения и каждый положил Qt5Core.dll рядом с exe. По-Вашему выходит а памяти будут 2 копии этой dll - ну если "не касается". В это слабо верится, что за dll если каждый процесс ее опять загружает? Естественно предположить что в памяти будет одна, отмапленная в адресное пр-во каждого процесса.

Если разные файлы, то и либа грузится дважды (в линукс скорее всего  по inode идет сверка).


Название: Re: Совместимлсть Qt dll
Отправлено: xokc от Июнь 25, 2014, 11:41
По-Вашему выходит а памяти будут 2 копии этой dll - ну если "не касается".
Так а Вы сами и проверьте - несложно ведь! Заодно и нам тут расскажите как всё обстоит на самом деле.


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 25, 2014, 11:57
Если разные файлы, то и либа грузится дважды (в линукс скорее всего  по inode идет сверка).
"разные файлы" - чего это ОС сразу станет искать по всем путям? И что считать "разными"? Как ни крути, а сначала должна быть проверка "устраивает ли та что уже в памяти"

Так а Вы сами и проверьте - несложно ведь! Заодно и нам тут расскажите как всё обстоит на самом деле.
Это универсальный ответ на любой вопрос :) А хотелось сначала ознакомиться с теорией - и услышать советы знатоков  :)


Название: Re: Совместимлсть Qt dll
Отправлено: alex312 от Июнь 25, 2014, 12:10
Это универсальный ответ на любой вопрос :) А хотелось сначала ознакомиться с теорией - и услышать советы знатоков  :)
http://msdn.microsoft.com/en-us/library/7d83bc18.aspx


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 25, 2014, 16:41
http://msdn.microsoft.com/en-us/library/7d83bc18.aspx
Ну Вы же прекрасно поняли что речь не о том в каком порядке пути перебираются - так к чему этот "тыц"  :)


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 25, 2014, 20:51
Если бы была одна dll на всех, то система была бы подвержена постоянной угрозе) Сделай библиотеке какой-нибудь code injection и всё, все приложения танцуют под твою дудку  ;D Хотя так было в Windows 3.1, если я не ошибаюсь!))
А теперь приходится писать драйвер уровня ядра, чтобы отслеживать загрузку библиотеки в память и налету каждую обрабатывать  :'(


Название: Re: Совместимлсть Qt dll
Отправлено: Alex Custov от Июнь 25, 2014, 21:58
Верю, но как пощупать?

Что значит пощупать? Убедиться что так и есть? Ну, скомпилировать какой-нибудь плагин с 5.0, и протестировать его на всех версиях с 5.0 до 5.3.1.

Да хотя бы в Вашей, напр MSDN пишет

Это касается только одного процесса, уже в принципе сказали.


Название: Re: Совместимлсть Qt dll
Отправлено: alex312 от Июнь 26, 2014, 01:30
Ну Вы же прекрасно поняли что речь не о том в каком порядке пути перебираются - так к чему этот "тыц"  :)
после таких вот ваших заявлений
Как ни крути, а сначала должна быть проверка "устраивает ли та что уже в памяти"
решил привести ссылку.
А по теме :
https://blog.qt.digia.com/blog/2009/08/12/some-thoughts-on-binary-compatibility/
http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++ (http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++)
http://techbase.kde.org/Policies/Binary_Compatibility_Examples


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 26, 2014, 15:50
Это касается только одного процесса, уже в принципе сказали.
после таких вот ваших заявлений
Как ни крути, а сначала должна быть проверка "устраивает ли та что уже в памяти"
решил привести ссылку.
Не надо "поджимать губки", намекая типа "ах как вы безграмотны, делаете такие заявления!"  :)
Хорошо, давайте так: на 1 машине 10 Qt приложений, каждое имеет Qt5Core.dll рядом с exe. Если все 10 приложений запущены - сколько копий Qt5Core.dll будет загружено в память? Все 10? Я не знаю "правельный ответ", но очень сомневаюсь что все 10 т.к.

- это выглядит глупо и противоречит идее dll

- выходит "всегда юзается та dll что рядом c exe - что-то слишком просто. Напр зачем тогда эта городушка http://msdn.microsoft.com/en-us/library/windows/desktop/ms682600%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682600%28v=vs.85%29.aspx)


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июнь 26, 2014, 15:55
Думаю будет загружено 10 штук.
Почему это глупо, подскажите пожалуйста?
Это было бы глупо, если бы в приложении 10 раз подгружалась 1 dll :)

А механизм поиска dll известен - рядом с файлом(для ярлыков в рабочем каталоге), потом по path и системным каталогам.


Название: Re: Совместимлсть Qt dll
Отправлено: Alex Custov от Июнь 26, 2014, 16:05
- это выглядит глупо и противоречит идее dll

идея dll - это dll в каком-либо системном каталоге, откуда её могут подгружать те кому надо, как Linux. В Windows всё немного по-другому. Если Qt каким-то образом установлен в системный каталог, то 10 Qt приложенгий могут загрузить Qt5Core из него, и скорее всего, что в памяти будет только одна копия dll. Случай же с dll, которая лежит рядом с exe - другой. Поэтому либо ОС обязана проверять сходность нашей dll со всеми теми, что уже загружены в памяти, либо просто игнорировать тот факт, что в памяти уже могут быть точно такие же dll и грузить ещё одну, нашу копию. Что на будет делать в реальности я не знаю, такой информации у меня нет, хотя я и склоняюсь к 10 копиям просто по логике.


Название: Re: Совместимлсть Qt dll
Отправлено: alex312 от Июнь 26, 2014, 19:35
Хорошо, давайте так: на 1 машине 10 Qt приложений, каждое имеет Qt5Core.dll рядом с exe. Если все 10 приложений запущены - сколько копий Qt5Core.dll будет загружено в память? Все 10? Я не знаю "правельный ответ", но очень сомневаюсь что все 10 т.к.
За 10 не скажу, но 2 приложения у меня сейчас работают каждое со своей копией Qt5Core.dll .


Название: Re: Совместимлсть Qt dll
Отправлено: Serr500 от Июнь 27, 2014, 12:26
- выходит "всегда юзается та dll что рядом c exe - что-то слишком просто. Напр зачем тогда эта городушка http://msdn.microsoft.com/en-us/library/windows/desktop/ms682600%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682600%28v=vs.85%29.aspx)
Эта "городушка" работает немного не так, как обычно думают. Если вы через LoadLibrary в коде грузите DLL с указанием абсолютного пути, то при наличии .local-файла абсолютный путь будет проигнорирован и поиск начнётся с каталога .exe-файла.


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 27, 2014, 12:52
Думаю будет загружено 10 штук.
Почему это глупо, подскажите пожалуйста?
Пример: Qt dll-ки в памяти занимают... ну много, метров 30 (не проверял, может и больше). 10 запущенных Qt приложений - вполне реально. Расход физической памяти 300 метров (вместо 30). По нынешним временам не катастрофа, но, мягко говоря, "не по-хозяйски".

За 10 не скажу, но 2 приложения у меня сейчас работают каждое со своей копией Qt5Core.dll .
Подтверждаю для 3-х  :)

Эта "городушка" работает немного не так, как обычно думают. Если вы через LoadLibrary в коде грузите DLL с указанием абсолютного пути, то при наличии .local-файла абсолютный путь будет проигнорирован и поиск начнётся с каталога .exe-файла.
Т.е. предполагается такой сценарий: инсталлятор куда-то слил dll-ки и, возможно, прописал path. Неск приложений оттуда грузят. Теперь dll-ки обновилось, а одно из приложений это не устраивает. И вот тогда с помощью redirection его можно "подлечить". Хтозна-шо  :'(



Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 27, 2014, 12:57
Да, к чему я все это спрашиваю: у меня 4 модуля, изначально в 1 фолдере, но один из них обычно интенсивно копируется в рамках одной машины, нередко 6-8 раз. Как лучше организовать dll-ки на Вындоуз?

Спасибо


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июнь 27, 2014, 13:16
Эмм...
А как оно копируется? модуль ваш? с dll или без?
Как вариант симлинки на ваши dll али же в system32 запихать.


Название: Re: Совместимлсть Qt dll
Отправлено: Serr500 от Июнь 27, 2014, 14:04
Т.е. предполагается такой сценарий: инсталлятор куда-то слил dll-ки и, возможно, прописал path. Неск приложений оттуда грузят. Теперь dll-ки обновилось, а одно из приложений это не устраивает. И вот тогда с помощью redirection его можно "подлечить". Хтозна-шо  :'(
Следствие недостаточно продуманной архитектуры первых версий Windows...  :-\ Потом придумали WinSxS...


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 27, 2014, 14:22
Да копия у каждого приложения, копия!

Иначе что, сделал QLibrary::unload () и все, крах системы?  ;D ;D ;D ;D

Если нужна только одна dll-ка, то берем системное API и нагло насилуем библиотеку какого-нибудь одного приложения  ;D


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 27, 2014, 17:44
Эмм...
А как оно копируется? модуль ваш? с dll или без?
Как вариант симлинки на ваши dll али же в system32 запихать.
Нет уж, в system32 ничего пихать не будем  >:(
Допустим простейший вариант: кладем  все рядом с exe. Тогда придется вдаваться в не очень удобные объяснения типа  "Вы ж все что начинается с "Q" тоже копируйте" + расход памяти.

Конечно копированием одного exe все равно не обойтись, поэтому пользователи уже приучены копировать фолдер Resources, это не вызовет никаких вопросов. Заметно лучше было бы слить dll-ки туда, но тогда нет никаких гарантий что там они найдутся первыми. Кстати пробовал подсунуть др Qt5Core.dll - он ее хватает и вякает что плохая.

А лучше всего было бы создать фолдер с именем DLL и туда все лить - но опять-таки, как обеспечить надежную "находимость"?

Да копия у каждого приложения, копия!

Иначе что, сделал QLibrary::unload () и все, крах системы?  ;D ;D ;D ;D
unload уменьшает счетчик ссылок, неоднократно встречал это упоминание

Если нужна только одна dll-ка, то берем системное API и нагло насилуем библиотеку какого-нибудь одного приложения  ;D
Каким образом? Изложите план насилия  :)


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 27, 2014, 19:27
Ведется подсчет ссылок внутри процесса и выгрузится он из этого процесса, а не из памяти.
А вот статейка про то самое  :)
http://www.codeproject.com/Tips/139349/Getting-the-address-of-a-function-in-a-DLL-loaded


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 28, 2014, 09:55
Ведется подсчет ссылок внутри процесса и выгрузится он из этого процесса, а не из памяти.
А вот статейка про то самое  :)
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), никакого другого "идентификатора версии" они не имеют (нет его и в манифестах что в ресурсах).

Правильно ли я понял? Какие др мнения?

Спасибо


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 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.

Перехваты можно разделить на два типа: локальные (перехват в пределах одного процесса) и глобальные (в масштабах всей системы).


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 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 в нем
остается прежним.


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 30, 2014, 11:31
Dll не берется из памяти, если такая же уже загружена... Она всегда берется с диска..
MSDN пишет http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx (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 копии.

Почитайте ради интереса статейки.
А Вы их сами внимательно читали? :) Давайте попробуем вместе
Цитировать
Система поддерживает в каждом процессе свой счетчик DLL, т. е. если поток
процесса А вызывает приведенную ниже функцию, а затем тот же вызов делает поток
в процессе В, то MyLib.dll проецируется на адресное пространство обоих процессов,
а счетчики числа пользователей DLL в каждом из них приравниваются 1.
Нема квешнзов, dll используется ОДНА, "проекций" может быть сколько угодно

Цитировать
Если же поток процесса В вызовет далее:
FreeLibrary(hinstDll);
счетчик числа пользователей DLL в процессе В обнулится, что приведет к отключению DLL от адресного пространства процесса В. Но проекция DLL на адресное пространство процесса А не затрагивается, и счетчик числа пользователей DLL в нем остается прежним.
Тоже все ясно, dll в памяти пока ею пользуется хоть один процесс


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 30, 2014, 12:23
MSDN говорит о загрузке библиотеки внутри одного процесса, а не среди нескольких.

Цитировать
Здесь важно "same module name" - это должен быть "именно тот файл" (а не др хоть и идентичный) 

- это просто имя файла библиотеки и ничего больше. Соответственно, следуя Вашей логике, система Windows не может содержать в памяти несколько библиотек с одинаковыми именами...
И почему это приложение отказывается стартовать, если не видит библиотеки на диске, хоть и приложение с такой же библиотекой будет одновременно работать?


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 30, 2014, 13:55
MSDN говорит о загрузке библиотеки внутри одного процесса, а не среди нескольких.
Покажите где это написано

И почему это приложение отказывается стартовать, если не видит библиотеки на диске, хоть и приложение с такой же библиотекой будет одновременно работать?
Она ищет "модуль" - файл на диске. Если его нет - все, отказ. Если же файл найден, то второй раз этот модуль не грузится, мапится то что уже в памяти.

Да, и какая Ваша версия/сценарий? "берется с диска" - что куда берется? :) Не очень понял что Вы утвержаете, объясните


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 30, 2014, 14:27
Там и обратного четко не прописано к всеобщему сожалению..

А как проверяется соответствие модуля с диска модулю в памяти?

Моя версия проста - если в местах поиска dll ее нет, то ничего и не загрузится, а если есть, то загружается непосредственно эта найденная dll в память процесса и больше никуда.
Я говорю это не по наслышке, а по опыту. Мне приходилось в свое время патчить системные библиотеки во время их загрузки в память процессов. При чем набор этих библиотек был ограничен и требовало его более 10-20 процессов, запускаемых поочередно. И единственным способом было - отлов каждого "события" загрузки dll и подмена этих dll для каждого процесса. Был бы механизм, который берет библиотеку из памяти, этих мытарств можно было бы избежать, но к сожалению, это не так.



Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июнь 30, 2014, 18:02
А как проверяется соответствие модуля с диска модулю в памяти?
Полагаю что никак, файл тот же, удалить/изменить нельзя, ну и все

Моя версия проста - если в местах поиска dll ее нет, то ничего и не загрузится,
Полностью согласен

а если есть, то загружается непосредственно эта найденная dll в память процесса и больше никуда.
Не согласен. Это противоречит здравому смыслу и многим цитатам выше (в том числе что и Вы привели). Два и более процессов используют один и тот же код dll, каждый в своем адресном пр-ве, но копия кода одна

Я говорю это не по наслышке, а по опыту. Мне приходилось в свое время патчить системные библиотеки во время их загрузки в память процессов. При чем набор этих библиотек был ограничен и требовало его более 10-20 процессов, запускаемых поочередно. И единственным способом было - отлов каждого "события" загрузки dll и подмена этих dll для каждого процесса. Был бы механизм, который берет библиотеку из памяти, этих мытарств можно было бы избежать, но к сожалению, это не так.
Значит что-то не так делали (понимаю - легко говорить). Что за "события", как подменяли и.т.п - расскажите


Название: Re: Совместимлсть Qt dll
Отправлено: Old от Июнь 30, 2014, 19:25
Значит что-то не так делали (понимаю - легко говорить). Что за "события", как подменяли и.т.п - расскажите
Думаю, тут количество вариантов сделать "не так" стремиться к нулю.
По логике, если процесс решил изменить общий ресурс, то происходит копирование кода библиотеки (тот самый copy-on-write).
Т.е. три процесса используют общую библиотеку system32.dll (refCount = 3) , один процесс решает ее пропатчить, для него создается ее копия и она становится в памяти другой библиотекой. Два других проект по прежнему используют system32.dll и если запуститься процесс, которому она понадобиться, то она будет мапиться к нему а адресное пространство. А пропатченная библиотека останется, у того процесса, который ее изменил и она для загрузчика уже не будет system32.dll, т.е. она делиться с другими процессами не будет.


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июнь 30, 2014, 20:02
Да, наверно все же в памяти что-то остается. И она копируется между процессами.
Забыли мы главное доказательство так сказать!) Ведь библиотеки могут иметь область shared, которая может быть доступна всем процессам, которые юзают эту библиотеку :)
Стало быть, да, библиотека сидит в памяти и отображается в память процессов, которые требуют именно эту библиотеку. А именно эта библиотека определяется путем на диске. Жаль конечно, что истинных кишков этого механизма врядли найдешь в открытом доступе, хотя можно в ReactOS поинтересоваться.
Всегда приятно открывать что-то новое  :D
Думаю, на этом спор можно считать законченым?)


Название: Re: Совместимлсть Qt dll
Отправлено: navrocky от Июль 01, 2014, 08:08
Я когда-то читал, что в Win9x библиотеки шарятся, в WinNT+ - нет, т.е. для каждого процесса отдельно грузятся. Это было сделано из принципов безопасности.


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июль 01, 2014, 10:01
Да я тоже такое читал, однако с __attribute__((section (".shared"), shared)) все работает и шарится.
В общем, очередной раз понимаю, какая же шарашкина контора эта винда  ;D


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 01, 2014, 12:07
Да, вроде разобрались. Теперь как насчет практического/утилитарного аспекта? (проще говоря как деплоить на Вындоуз)?

Допустим простейший вариант: кладем  все рядом с exe. Тогда придется вдаваться в не очень удобные объяснения типа  "Вы ж все что начинается с "Q" тоже копируйте" + расход памяти.

Конечно копированием одного exe все равно не обойтись, поэтому пользователи уже приучены копировать фолдер Resources, это не вызовет никаких вопросов. Заметно лучше было бы слить dll-ки туда, но тогда нет никаких гарантий что там они найдутся первыми. Кстати пробовал подсунуть др Qt5Core.dll - он ее хватает и вякает что плохая.

А лучше всего было бы создать фолдер с именем DLL и туда все лить - но опять-таки, как обеспечить надежную "находимость"?


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июль 01, 2014, 13:14
Igors, уточните вопрос пожалуйста, а то лень перечитывать всю дискуссию, чтобы вспомнить где собака порылась  ;D


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 01, 2014, 13:40
Есть 4 exe модуля - ну теперь все с Qt. После установки все лежат в оной папке/мамке. Однако один exe-шник пользователи часто копируют (вернее 2 вместе) в рамках 1 машины. Вариант "копируйте вместе со всеми dll-ками" будет работать, но не выглядит элегантным. Как организовать грамотно?


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июль 01, 2014, 14:30
Плюньте на всё, напишите загрузчик на winApi и его пусть копируют. А сам загрузчик будет лезть в реестр, находить папку с программой и запускать необходимые приложения.
Для вас это гораздо проще, чем таскать "тонны" dll :D


Название: Re: Совместимлсть Qt dll
Отправлено: OKTA от Июль 01, 2014, 14:41
Как вариант, можно извернуться и сделать предстартовое приложение маленькое, которое делает вот это http://msdn.microsoft.com/en-us/library/windows/desktop/ms686203%28v=vs.85%29.aspx
а потом запускает основное в виде dll, которое упаковать вместе с этим предстартовым приложением  ;D
Диковато, но зато не таскать все библиотеки  ;D


Название: Re: Совместимлсть Qt dll
Отправлено: navrocky от Июль 01, 2014, 17:43
Есть 4 exe модуля - ну теперь все с Qt. После установки все лежат в оной папке/мамке. Однако один exe-шник пользователи часто копируют (вернее 2 вместе) в рамках 1 машины. Вариант "копируйте вместе со всеми dll-ками" будет работать, но не выглядит элегантным. Как организовать грамотно?

Ваши предложения взрывают мозг. Однако, предполагаю, что речь идет о распространении собранного приложения на Qt5 под windows?

Если так, то все необходимые либы надо таскать с собой и ни в коем случае не совать в общие папки типа c:\windows\system32. Самое правильное - написать для этого инсталлятор. NSIS, MSI или что-то другое на ваш выбор.

Ну или собрать статику, если не смущают ограничения LGPL лицензии ;) Хотя сборка статики, сама по себе задачка не простая.


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 01, 2014, 18:22
Ваши предложения взрывают мозг. Однако, предполагаю, что речь идет о распространении собранного приложения на Qt5 под windows?
Не только, речь идет о том что некоторые модули приложения могут/будут копироваться

Статика не катит - есть обильные плагины. Инсталлятор есть, им занимается др человек. Ну я могу ему сказать типа "эти файлы должны быть там-то", он сделает. И что с того, где файлы-то класть?

Плюньте на всё, напишите загрузчик на winApi и его пусть копируют. А сам загрузчик будет лезть в реестр, находить папку с программой и запускать необходимые приложения.
Для вас это гораздо проще, чем таскать "тонны" dll :D
Не вижу как это избавляет от dll. И пользователь копирует не для того чтобы запустить неск "instances" одного модуля. Напротив, цель - запустить неск exe, каждый по сети получает свою задачу.

Как вариант, можно извернуться и сделать предстартовое приложение маленькое, которое делает вот это http://msdn.microsoft.com/en-us/library/windows/desktop/ms686203%28v=vs.85%29.aspx
а потом запускает основное в виде dll, которое упаковать вместе с этим предстартовым приложением  ;D
Диковато, но зато не таскать все библиотеки  ;D
Сейчас происходит так, пример: есть "свободная машина" - юзер копирует туда 2 exe-iшки: одна "слушает сеть", другая считает (возможно долго). Результаты отправляются обратно по сети. Или то же самое в рамках 1 машины. Главный модуль (генератор заданий) требует инсталла, с этим никто не спорит. Но делать инсталл для каждого модуля - ну никак не хочется


Название: Re: Совместимлсть Qt dll
Отправлено: Old от Июль 01, 2014, 18:26
Не только, речь идет о том что некоторые модули приложения могут/будут копироваться
Какой в этом смысл?
Можно создать два батника, которые и будут запускать программы. Пусть они эти батники копируют.


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июль 01, 2014, 18:48
Берём и делаем такую структуру
Код:
path/bin/
            1.exe // program 1
            2.exe // program 2
            3.exe // program 3
            4.exe // program 4
            *.dll // some dll/plugin/
path/
       1.exe // win api loader
       2.exe // copy loader
       3.exe // copy loader
       4.exe // copy loader

При установке в реестр прописываем путь "path/bin/"

Псевдокод loader
Код:
// функция, которая получает путь к каталогу с бинарниками программ.
dir=GetRegistryPathMyProgram();
// dir="path/bin/"
// получаем имя процесса
file=GetProcessName();
// file=имя текущего лоадера ([1-4].exe)
startProcess(dir+file);

PS понятно, что уязвимость переименования есть, но это лишь для понимания сути моей идеи.
PPS можно и 4 экземпляра лоадера собирать, ничего сложного нет, только менять file.
PPPS в результате у нас программы лежат спокойно и жрут одни dll и плагины. Лоадеры будут очень лёгкими и переносимыми в пределах компа, на котором установлена программа.


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 03, 2014, 08:34
Лоадеры будут очень лёгкими и переносимыми в пределах компа, на котором установлена программа.
Цель - запуск нескольких (скопированных) exe (а не instance(s) одного модуля). Подразумевается копирование всех плагинов и необходимых файлов. Это однообразно на Win/OSX (там вторую копию юзер не запустит) и без разницы "'эта машина или другая".


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июль 03, 2014, 10:41
Вы хотите без топора срубить дерево.
Перенести программу без установки? Пожалуйста, усложните лоадер на внесение/изменение записи в реестре при наличие рядом с ним каталога с dll и вашими модулями. И напишите предупреждение в лоадере, типа "для работы программы необходимо переносить каталог bin в папке с запускаемым файлом".

Хотите перенести программу копированием лоадера? Вспоминается...
Цитировать
Вопрос в службу поддержки:
Уважаемая служба поддержки, я хочу сохранить фильм на дискету, но компьютер мне пишет, что недостаточно места, поэтому мне приходится сохранять ярлык. Если я хочу посмотреть фильм на другом компьютере, то он мне выдает ошибку, что файл не найден. Но ведь на моем компьютере фильм прекрасно проигрывается! В чем проблема?
С дружеским приветом, Катя Иванова


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 05, 2014, 09:19
Попытаюсь оживить тему. Что можно придумать кроме "класть рядом с exe-шкой"?

1) Инсталлятор прописывает path. Ну любой др инсталлятор (включая мой же в след версии) сделает то же. Какие dll найдутся - как бог пошлет.

2) Делать какой-то "загрузчик". Заботы уже имею (хотя бы алерты в WinAPI), но что достигается? Как я понял предыдущего докладчика, теперь загрузчик можно куда угодно копировать, из любой точки он запустит "ту самую" exe. Толку ноль, запуск 2 и более копий не поддерживается, а для одной гораздо проще опять-таки положить рядом.

3) Хотелось бы так: стартануть, самому найти и загрузить все нужные dll, удостовериться что все они Ok, а потом уж запускать бандуру с UI на Qt. Вот на OSX есть "weak" линковка (нашли либу или нет - все равно стартовать). Но на Вындоуз я про это ничего не слышал.

4) Еще предложения ?

Спасибо


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июль 05, 2014, 09:32
По 2 пункту вы выразились туманно. Какое то ограничение на 2 копии и запуск "той самой exe".
Никаких ограничений нет, загрузчик играет роль ярлыка.


Название: Re: Совместимлсть Qt dll
Отправлено: Old от Июль 05, 2014, 09:47
Толку ноль, запуск 2 и более копий не поддерживается, а для одной гораздо проще опять-таки положить рядом.
Почему не поддерживается? Поддерживается.

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


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 05, 2014, 10:28
Здесь хватит простого командного файла,
..
Даже простых ярлыков должно хватить,
Конечно можно. Но требования заказчика (в общих чертах) "должно быть солидно, никаких (е)батников". И, по большому счету, он прав


Название: Re: Совместимлсть Qt dll
Отправлено: Old от Июль 05, 2014, 10:33
Огласите список солидностей. :) Сейчас, пользователь копирует несколько exe с dll и это солидно, а копировать один файлик, это не солидно.

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


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июль 05, 2014, 11:16
Если солидно, то берём, всё запаковываем в лаунчер, лаунчер при запуске в темп кладёт программу и запускает :D И чорненькую рамочку лаунчеру. Тогда точно солидно, мб на 40 получится exe :)

PS bat'ник поправить может каждый. А вот расковырять лаунчер надо постараться :D


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 05, 2014, 11:31
Огласите список солидностей. :) Сейчас, пользователь копирует несколько exe с dll и это солидно, а копировать один файлик, это не солидно.
Список очень прост если Вы знакомы с Mac. Хорошим тоном считается отсутствие какого-либо инсталлятора, установка сводится к копированию приложения (или фолдера приложения) куда угодно, рекомендуется в Application. Некультурно разбрасывать либы, пусть и в своем фолдере, их надо помещать в "bundlle" приложения.

"Копировать фолдер приложения" проходит и на Вындоуз (для данного проекта). Однако тут без инсталла не обойтись, хотя бы нужны рантаймы и др. Вот как бы мне Qt либы пристроить чтобы они не мозолили глаза и не грузились многократно?

Возня с батниками в эту схему не вписывается, не тратьте время


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 05, 2014, 11:35
Вот подумал - а если сделать какую-то свою маленькую dll которая грузится первой и разбирается с Qt либами делая для них LoadLibrary? Ведь если загружена в память процесса - искать на диске не должна.

Бред?


Название: Re: Совместимлсть Qt dll
Отправлено: Bepec от Июль 05, 2014, 11:50
На мак и реализована распаковка.
Тот же VLC скачиваем - один файл. Представляет собой zip архив определённой структуры. При запуске распаковывается куда то и запускается. Вот и весь сказ.


Название: Re: Совместимлсть Qt dll
Отправлено: Old от Июль 05, 2014, 11:55
Вот подумал - а если сделать какую-то свою маленькую dll которая грузится первой и разбирается с Qt либами делая для них LoadLibrary? Ведь если загружена в память процесса - искать на диске не должна.
Тогда пользователю нужно будет копировать эту библиотеку вместе с exe.

Для чего вы придумывает сложности?
Если не хотите батник,  то лучше один ланчер, чем два exe+dll.


Название: Re: Совместимлсть Qt dll
Отправлено: Old от Июль 05, 2014, 11:59
Возня с батниками в эту схему не вписывается, не тратьте время
Да, для кого то "солидность", а для других список дурных советов. :)


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 05, 2014, 12:15
Вот подумал - а если сделать какую-то свою маленькую dll которая грузится первой и разбирается с Qt либами делая для них LoadLibrary? Ведь если загружена в память процесса - искать на диске не должна.
Тогда пользователю нужно будет копировать эту библиотеку вместе с exe.
Как уже говорилось, никто и не ставит задачи "копировать один exe файл", нужно просто как-то "изолировать" толпу Qt dll, а будет еще один файл в фолдере приложения - нормально. Хорошо, а как добиться чтобы "вот эта " грузилась первой?

лучше один ланчер, чем два exe+dll.
А что это за ланчер, как он будет разбираться с копиями?


Название: Re: Совместимлсть Qt dll
Отправлено: Old от Июль 05, 2014, 12:29
Хорошо, а как добиться чтобы "вот эта " грузилась первой?
Порядком линковки (она должна идти первой) или с помощью pragma.

А что это за ланчер, как он будет разбираться с копиями?
А какие проблемы есть с копиями?
Ланчер должен делать ровно тоже, что и батник - готовить оуружение для правильной загрузки dll и зпускать нужный exe-шник.


Название: Re: Совместимлсть Qt dll
Отправлено: Igors от Июль 13, 2014, 11:03
Вот подумал - а если сделать какую-то свою маленькую dll которая грузится первой и разбирается с Qt либами делая для них LoadLibrary? Ведь если загружена в память процесса - искать на диске не должна.

Бред?
Наконец дошли руки проверить - да, бред :) Действительно желаемая dll "грузится" первой, но ее DLLMain еще не вызывается. Сначала грузятся все др dll (конечно включая Qt и конечно отлуп если не найдены). Только после этого дело доходит до задуманного DLLMain - а поезд-то уже ушел. Плюс предупреждают что нехорошо делать LoadLibrary в точке входа др dll (мол, возможен бесконечный рекурс).

Еще вариант - переделать приложение в dll а exe сделать полностью нативным, пусть оно проверяет и загружает нужные dll. Но как-то не тянет выполнять эту процедуру для 4 приложений. Да и кто знает, может будут проблемы напр с QApplication если компилируется как dll ?

Еще решения?