Russian Qt Forum
Ноябрь 23, 2024, 03:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как получить имя модуля dll  (Прочитано 10170 раз)
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« : Ноябрь 01, 2017, 08:10 »

Здравствуйте!
Мне нужно получить наименование dll и полный путь к ней. Для этого в dll использую функцию WINAPI GetModuleFileName():
Код:
char dllname[_MAX_PATH] = {0};
::GetModuleFileName( NULL, (LPWSTR)dllname, sizeof(dllname) );
QString qstr=dllname;
qDebug()<<qstr;
В результате в dllname получаю массив символов Unicode - полный путь и имя .exe файла, загружающего dll.
Как сделать правильно?

« Последнее редактирование: Ноябрь 01, 2017, 10:08 от Bolonat » Записан
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« Ответ #1 : Ноябрь 01, 2017, 10:08 »

Какой-то замкнутый круг получается... Я получаю путь и  имя exe вместо пути и имени dll, потому что в GetModuleFileName() указываю первый параметр NULL. А получить HMODULE или HINSTANCE dll-ки  можно только из WINAPI DllEntryPoint. То есть, если dll загружается из другого каталога, получается я путь к ней узнать не могу?    
« Последнее редактирование: Ноябрь 01, 2017, 10:55 от Bolonat » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #2 : Ноябрь 01, 2017, 10:25 »

Цитировать
Retrieves the fully qualified path for the file that contains the specified module. The module must have been loaded by the current process.

hModule [in, optional]
A handle to the loaded module whose path is being requested. If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
Записан
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« Ответ #3 : Ноябрь 01, 2017, 10:33 »

Цитировать
Retrieves the fully qualified path for the file that contains the specified module. The module must have been loaded by the current process.

hModule [in, optional]
A handle to the loaded module whose path is being requested. If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.

Как в Qt получить HMODULE или HINSTANCE dll-ки, чтобы передать его в GetModuleFileName()?

P.S. MSDN я тоже читаю...
« Последнее редактирование: Ноябрь 01, 2017, 10:43 от Bolonat » Записан
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« Ответ #4 : Ноябрь 01, 2017, 10:52 »

Попробовала вместо хэндла dll использовать хэндл окна:
Код:
::GetModuleFileName( (HMODULE)this->winId(), (LPWSTR)dllname, sizeof(dllname) );

Получаю массив, заполненный нулями.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Ноябрь 01, 2017, 11:11 »

Как в Qt получить HMODULE или HINSTANCE dll-ки, чтобы передать его в GetModuleFileName()?

P.S. MSDN я тоже читаю...
Можно получить из хендла путь и наоборот, а что Вы хотите - неясно. Может узнать в какой dll сидит текущий исполняемый код? (других разумных вариантов не видно). Тогда курите GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
Записан
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« Ответ #6 : Ноябрь 01, 2017, 11:18 »

Можно получить из хендла путь и наоборот, а что Вы хотите - неясно. Может узнать в какой dll сидит текущий исполняемый код? (других разумных вариантов не видно). Тогда курите GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
Я хочу получить имя модуля dll и путь к dll из самой dll. Если я снова выразилась неясно, пожалуйста, сообщите об этом сразу, не наблюдайте молча.
« Последнее редактирование: Ноябрь 01, 2017, 11:29 от Bolonat » Записан
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« Ответ #7 : Ноябрь 01, 2017, 14:04 »

Получилось. Кому интересно, хэндл dll в Qt под Win можно получить так:
Код:
static HMODULE GetThisDllHandle()
{
  MEMORY_BASIC_INFORMATION info;
  size_t len = VirtualQueryEx(GetCurrentProcess(), (void*)GetThisDllHandle, &info, sizeof(info));
  assert(len == sizeof(info));
  return len ? (HMODULE)info.AllocationBase : NULL;
}
а затем передать его в GetModuleFileName(). В результате получаем полный путь с именем dll из самой dll.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #8 : Ноябрь 01, 2017, 16:02 »

Это всё хорошо, но постановку задачи вы так и не сказали:)
Например, изначально было не ясно, что нужно получить путь к _своей_ dll, а не к какой-либо загруженной (напр., кутешной).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Ноябрь 01, 2017, 16:32 »

а не к какой-либо загруженной (напр., кутешной).
Напр так
Код
C++ (Qt)
typedef QString (*Func)(const char *, int);
Func func = &QString::fromLocal8Bit;
HMODULE hmodule = 0;
bool ok = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
   LPCTSTR(func),
&hmodule);
if (ok && hmodule) {
ushort path[MAX_PATH] = { 0 };
ok = GetModuleFileName(hmodule, path, MAX_PATH - 1);
QString fullName = QString::fromUtf16(path);
qDebug() << "ok =" << ok << "path =" << fullName;
}
 
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #10 : Ноябрь 01, 2017, 23:16 »

Получилось. Кому интересно, хэндл dll в Qt под Win можно получить так:
Код:
static HMODULE GetThisDllHandle()
{
  MEMORY_BASIC_INFORMATION info;
  size_t len = VirtualQueryEx(GetCurrentProcess(), (void*)GetThisDllHandle, &info, sizeof(info));
  assert(len == sizeof(info));
  return len ? (HMODULE)info.AllocationBase : NULL;
}
а затем передать его в GetModuleFileName(). В результате получаем полный путь с именем dll из самой dll.
а как это связано с Qt? обычные винапишные вызовы
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« Ответ #11 : Ноябрь 02, 2017, 07:55 »

Напр так [...]
Спасибо большое. В моих попытках применить  GetModuleHandleEx() с флагом GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, неизменно в hmodule возвращался 0. В вашем варианте все работает.

Это всё хорошо, но постановку задачи вы так и не сказали:)
А мне казалось, что все ясно Улыбающийся. Вообще, хочу чтобы ini файл настройки моей dll лежал рядом с dll, а не рядом с exe. Это на случай если dll и exe находятся в разных каталогах. Ну и... неплохо знать откуда загружается dll, если их несколько одинаковых(разных версий) валяется в разных местах ).

Цитировать
а как это связано с Qt?
Разработку веду в Qt.(Естественно, обычные винапишные. Как я понимаю, из-за кроссплатформенности Qt других и быть не может)
 
« Последнее редактирование: Ноябрь 02, 2017, 11:28 от Bolonat » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Ноябрь 02, 2017, 14:27 »

В моих попытках применить  GetModuleHandleEx() с флагом GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, неизменно в hmodule возвращался 0.
Нужен любой адрес кода (но не данных) сидящий в этой dll. Это может быть адрес ф-ции ((void*)GetThisDllHandle) или статического метода, (QString::fromLocal8Bit) но не обычного

обычные винапишные вызовы
И заметьте: когда до этого доходит дело - поклонники этой платформы ну прямо куда-то испаряются  Улыбающийся
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #13 : Ноябрь 03, 2017, 01:29 »

Разработку веду в Qt.(Естественно, обычные винапишные. Как я понимаю, из-за кроссплатформенности Qt других и быть не может)
 
не совсем понимаю это высказывание. При попытке скомпилировать этот код на платформе, отличной от виндоус, компилятор скажет «давай, до свидания», и кросс-платформенность Qt никак не поможет. Но этот же код будет прекрасно работать и оторванно от Qt (при компиляции под виндоус, естественно), если писать «просто» на С или С++. Суть в том, что вопрос чисто о виндоус-специфической вещи, которая к Qt никакого отношения не имеет.

да, и «разработку в Qt» вести нельзя Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Bolonat
Чайник
*
Offline Offline

Сообщений: 56


Qt Creator 4.5.0 на Qt 5.10.0 (W10 x64) MinGW 5.3.


Просмотр профиля
« Ответ #14 : Ноябрь 03, 2017, 08:18 »

Нужен любой адрес кода (но не данных) сидящий в этой dll. Это может быть адрес ф-ции ((void*)GetThisDllHandle) или статического метода, (QString::fromLocal8Bit) но не обычного
Aаа, теперь понятно - я просто "курить" не умею...)


не совсем понимаю это высказывание. При попытке скомпилировать этот код на платформе, отличной от виндоус, компилятор скажет «давай, до свидания», и кросс-платформенность Qt никак не поможет. Но этот же код будет прекрасно работать и оторванно от Qt (при компиляции под виндоус, естественно), если писать «просто» на С или С++. Суть в том, что вопрос чисто о виндоус-специфической вещи, которая к Qt никакого отношения не имеет.
Изначально, суть вопроса была - получить путь и наименование загруженной dll. Я не знала, есть ли Qt-шные методы и применила
"чисто виндоус-специфическую вещь" (благо, у меня не стоит задача разработать кроссплатформенное ПО), о чем и сообщила на форуме. Если бы кто-то предложил
другой способ, который имеет отношение к Qt, я бы с радостью применила его. Но сейчас я понимаю, что существование этого
способа маловероятно именно по причине кроссплатформенности Qt.    

« Последнее редактирование: Ноябрь 03, 2017, 12:37 от Bolonat » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.237 секунд. Запросов: 23.