Russian Qt Forum

Qt => Установка, сборка, отладка, тестирование => Тема начата: Torvald от Декабрь 12, 2016, 14:07



Название: [РЕШЕНО, но так себе] Грузит не ту DLL
Отправлено: Torvald от Декабрь 12, 2016, 14:07
Здравствуйте, возникла проблема:
на пользовательском компьютере "где-то" установлена библиотека libstdc++-6.dll, мое приложение грузит эту библиотеку и выдает ошибку "не найдена точка входа __gxx_personality_v0 ...".
Вероятно эта библиотека собрана другой версией MinGW.
В каталоге моего приложения уже есть все необходимые библиотеки (в тч libstdc++-6.dll), но оно почему то выбирает именно ту "неправильную", не из каталога приложения а извне.

Вопрос: как сказать приложению использовать библиотеку, которая лежит в том же каталоге?

Пробовал так, не помогает:
Код
C++ (Qt)
QStringList paths = QApplication::libraryPaths();
paths.append(".");
paths.append("platforms");
paths.append("imageformats");
paths.append(dllDir.absolutePath());
paths.append(dllDir.absolutePath() + "/platforms");
paths.append(dllDir.absolutePath() + "/imageformats");
QApplication::setLibraryPaths(paths);


Название: Re: Грузит не ту DLL
Отправлено: Пантер от Декабрь 12, 2016, 14:09
Так точно не получится. На сколько я помню, только менять переменную PATH перед запуском, типа set PATH=.;%PATH%
Пусть виндузятники меня поправят, если я не прав.


Название: Re: Грузит не ту DLL
Отправлено: Bepec от Декабрь 12, 2016, 14:36
Сначала ищется рядом с исполняемым файлом, потом в патче, потом в системных директориях.
Если у вас это происходит, значит нету этой длл рядом с exe.


Название: Re: Грузит не ту DLL
Отправлено: Пантер от Декабрь 12, 2016, 14:40
Сначала ищется рядом с исполняемым файлом, потом в патче, потом в системных директориях.
Если у вас это происходит, значит нету этой длл рядом с exe.
Are you sure?


Название: Re: Грузит не ту DLL
Отправлено: Пантер от Декабрь 12, 2016, 14:43
Таки да. Проверь рабочий каталог запуска.

Цитировать
If SafeDllSearchMode is enabled, the search order is as follows:
The directory from which the application loaded.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
If SafeDllSearchMode is disabled, the search order is as follows:
The directory from which the application loaded.
The current directory.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.


Название: Re: Грузит не ту DLL
Отправлено: Igors от Декабрь 12, 2016, 14:55
Сначала ищется рядом с исполняемым файлом,
На неубогом Вындоуз - да, но есть и др ОС


Название: Re: Грузит не ту DLL
Отправлено: Пантер от Декабрь 12, 2016, 14:55
Сначала ищется рядом с исполняемым файлом,
На неубогом Вындоуз - да, но есть и др ОС
Вопрос был конкретно про Вындоус.


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 12, 2016, 15:03
Если длл нет, то так и пишет - не найдена длл. Пробовал удалить libstdc++-6.dll из каталога приложения - ошибка не изменилась, все так же не находит точку входа __gxx_personality_v0.
Что интересно, собрал тестовое ехе приложение - все работает.
А вот в подгружаемой библиотеке - нет.
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка. Пробовал обнулять переменные среды - никакого эффекта. Пробовал повысить версию MinGW - ошибка изменилась (теперь другую точку входа найти не может).


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 12, 2016, 15:07
Таки да. Проверь рабочий каталог запуска.
Проверил - совпадает с каталогом запуска ехе и длл.

Попытался скомпилить с флагами -static-libgcc и -static-libstdc++, длл выросла, но ошибка не исчезла

И вообще эта ошибка на чистой системе не проявляется. Только вот на этом компьютере (Win7 32bit)


Название: Re: Грузит не ту DLL
Отправлено: Igors от Декабрь 12, 2016, 15:25
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка.
Так может просто в exe зашит путь загрузки? (weak/delayed dll)


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 12, 2016, 15:33
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка.
Так может просто в exe зашит путь загрузки? (weak/delayed dll)
Это я проверить не могу. Даже если это так, то как в этом случае загрузить длл? Почему на других компьютерах все работает?


Название: Re: Грузит не ту DLL
Отправлено: kuzulis от Декабрь 12, 2016, 19:32
Цитировать
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка.

Эмм... а разве так можно? Откуда дельфи знает про Qt?  :o
Или имеется ввиду, что dll-ка написана в QtCreator без использования Qt-шных классов?


Название: Re: Грузит не ту DLL
Отправлено: Пантер от Декабрь 12, 2016, 20:04
Цитировать
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка.

Эмм... а разве так можно? Откуда дельфи знает про Qt?  :o
Или имеется ввиду, что dll-ка написана в QtCreator без использования Qt-шных классов?
А Кьют выдает какие-то нестандартные dll?


Название: Re: Грузит не ту DLL
Отправлено: Bepec от Декабрь 12, 2016, 20:07
конфликт дллок скорее всего.
Если приложение использует длл с тем же названием,но другой версии/компилятора, то при неявной подгрзке dll будет подсунута не та, которая рядом с Dll, а та, что загружена приложением.


Название: Re: Грузит не ту DLL
Отправлено: Пантер от Декабрь 12, 2016, 20:10
DLLHell


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 13, 2016, 11:17
Цитировать
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка.

Эмм... а разве так можно? Откуда дельфи знает про Qt?  :o
Или имеется ввиду, что dll-ка написана в QtCreator без использования Qt-шных классов?

Конечно можно, дельфи вообще без разницы на чем написана длл. Он просто грузит длл и вызывает из нее мою функцию в которой уже запускается кутишный цикл событий и все такое. Вот в это время (скорее всего при создании QApplication) начинается подгрузка кутишный библиотек, которые лежат рядом. Все грузятся нормально, кроме libstdc++-6.dll.


Название: Re: Грузит не ту DLL
Отправлено: gil9red от Декабрь 13, 2016, 11:56
Цитировать
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка.

Эмм... а разве так можно? Откуда дельфи знает про Qt?  :o
Или имеется ввиду, что dll-ка написана в QtCreator без использования Qt-шных классов?

Конечно можно, дельфи вообще без разницы на чем написана длл. Он просто грузит длл и вызывает из нее мою функцию в которой уже запускается кутишный цикл событий и все такое. Вот в это время (скорее всего при создании QApplication) начинается подгрузка кутишный библиотек, которые лежат рядом. Все грузятся нормально, кроме libstdc++-6.dll.

А как же бинарная совместимость? Если компиляторы dll и exe разные используются?


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 13, 2016, 12:01
Цитировать
На самом деле это delphi проект, который грузить dll написанную на Qt, и вот при загрузке этой длл возникает эта ошибка.

Эмм... а разве так можно? Откуда дельфи знает про Qt?  :o
Или имеется ввиду, что dll-ка написана в QtCreator без использования Qt-шных классов?

Конечно можно, дельфи вообще без разницы на чем написана длл. Он просто грузит длл и вызывает из нее мою функцию в которой уже запускается кутишный цикл событий и все такое. Вот в это время (скорее всего при создании QApplication) начинается подгрузка кутишный библиотек, которые лежат рядом. Все грузятся нормально, кроме libstdc++-6.dll.

А как же бинарная совместимость? Если компиляторы dll и exe разные используются?

Это важно только на стадии линковки. При динамической загрузке не важно какой там компилятор - машинный код же. Хоть на прологе пиши длл


Название: Re: Грузит не ту DLL
Отправлено: Авварон от Декабрь 13, 2016, 13:07
А как же бинарная совместимость? Если компиляторы dll и exe разные используются?

ABI С стандартизован, как и code conventions. Можно из дллки отрезолвить сишную функцию (с правильным code convention) и вызвать её.
Неважно из какого языка.
Плюсовую функцию нельзя, потому что mangnling имен не стандартизован и неизвестно, как она реально называется.


Название: Re: Грузит не ту DLL
Отправлено: Igors от Декабрь 13, 2016, 16:59
Вот в это время (скорее всего при создании QApplication) начинается подгрузка кутишный библиотек, которые лежат рядом. Все грузятся нормально, кроме libstdc++-6.dll.
Обычно это не так, либы грузятся до загрузки модуля который их требует. Если хоть с одной не вышло - до main дело не дойдет. В консоли отладчика (по крайней мере на MSVC) показываются загружаемые модули. Я бы начал с выяснения кому нужна эта libstdc++-6.dll. Сделал бы тестовое приложение (абы запустилось) и посмотрел бы перед какой либой грузится libstdc.


Название: Re: Грузит не ту DLL
Отправлено: Bepec от Декабрь 13, 2016, 21:29
Неее, половина Qt теперь на плагинах построена.
Которые занимаются непосредственным резолвингом функций уже после загрузки приложения. Там у них тупо вбито "LoadLibrary" и "GetProcAddress".
Поэтому даже загрузка приложения != подгрузка всех библиотек. Сам с этим сталкивался, когда с бдшками работал и сетью.


Название: Re: Грузит не ту DLL
Отправлено: Igors от Декабрь 14, 2016, 12:14
Неее, половина Qt теперь на плагинах построена.
Которые занимаются непосредственным резолвингом функций уже после загрузки приложения. Там у них тупо вбито "LoadLibrary" и "GetProcAddress".
Для данной либы (libstdc) слишком много пришлось бы резолвить

Проблема в том что неубогое Вындоуз наверное не позволит загрузить др либу хоть откуда если либа с таким именем уже в памяти процесса. Придется как-то переименовывать (libstdZ что ли) и править ссылки во всех использующих либах. Уродство конечно. Или линковать всю свою либу статычно чтобы избавиться от зависимости libstdc

Впрочем послушаем тех кто утверждал что Вындоуз впереди планеты всей  :)


Название: Re: Грузит не ту DLL
Отправлено: Пантер от Декабрь 14, 2016, 12:22
Мда, в Винде действительно геморрой с dll. В Линухе все намного удобнее - LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./prog и все работает.


Название: Re: Грузит не ту DLL
Отправлено: lit-uriy от Декабрь 14, 2016, 13:31
>>Вындоуз наверное не позволит загрузить др либу хоть откуда если либа с таким именем уже в памяти процесса.
а откуда она появилась в памяти процесса?
Это типа такой зоопарк у процесса что ему одновременно нужны DLL-ки с одинаковым именем, но совершенно не совместимые между собой?


Название: Re: Грузит не ту DLL
Отправлено: Bepec от Декабрь 14, 2016, 13:57
А Linux позволяет загрузить в приложение 2 версии одной Dll? Рили?


Название: Re: Грузит не ту DLL
Отправлено: Igors от Декабрь 14, 2016, 14:17
А Linux позволяет загрузить в приложение 2 версии одной Dll? Рили?
Про линукс ничего не скажу, а OSX точно позволяет


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 14, 2016, 15:38
Хм, а можно как то узнать какие переменные окружения задает приложение при запуске? И как узнать какая  именно длл подгружается, по какому пути?


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 14, 2016, 16:12
Нашел откуда грузилась библиотека. Из некой FileZilla. Почему оттуда - непонятно, видимо родительское приложение как то неявно туда указывает или его переменные окружения не определены, а для FileZilla установлены глобально

Короче говоря основное приложение загружает кучу всяких модулей. Часть из них используют одну версию libstdc++-6.dll, часть - другую. Что делать в этой ситуации не понятно. Это какая то каша из длл которые ссылаются на другие длл которые ссылаются на общие длл но разных версий %)


Название: Re: Грузит не ту DLL
Отправлено: Torvald от Декабрь 14, 2016, 17:03
Короче я просто переименовал libstdc++-6.dll в libstdc++-X.dll и заменил все ее упоминания во всех своих зависимых длл. Очень грязный хак, но как быстрое временное решение пока сойдет.

Всем большое спасибо за помощь. Вот уж точно dll hell :c


Название: Re: Грузит не ту DLL
Отправлено: Igors от Декабрь 15, 2016, 12:43
Короче я просто переименовал libstdc++-6.dll в libstdc++-X.dll и заменил все ее упоминания во всех своих зависимых длл. Очень грязный хак, но как быстрое временное решение пока сойдет.
Очень может быть что на данном ОС лучшего решения и объективно нет. Так что не переживайте и
Цитировать
Нет ничего более постоянного чем временное
:)


Название: Re: [РЕШЕНО, но так себе] Грузит не ту DLL
Отправлено: Bepec от Декабрь 15, 2016, 22:24
Да, нет решения. Ибо чтобы поменять данную систему, нужно сначала новую разработать и обеспечить совместимость со старой :)