Форум программистов, компьютерный форум CyberForum.ru

C++ и WinAPI

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.97
Limb0
 Аватар для Limb0
19 / 19 / 0
Регистрация: 22.01.2012
Сообщений: 88
#1

Как правильно использовать GetModuleFileName? - C++ WinAPI

13.09.2013, 14:03. Просмотров 4151. Ответов 8
Метки нет (Все метки)

Здравствуйте, есть следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <Windows.h>
 
using namespace std;
 
int main ()
{   LPWSTR buffer;
    GetModuleFileName(NULL, buffer, MAX_PATH) ;
    cout<<buffer;
    cin.get();
    cin.get();
    
}
Который должен показывать полный путь откуда запускается программа. Но в VS 2012 у меня появляется ошибка:
Ошибка 1 error C4700: использована неинициализированная локальная переменная "buffer"
Что в коде не так? Можно ли как-то заменить LPWSTR на стандартный тип.

Добавлено через 43 минуты
Уже нашел ответ, нужно было просто написать wchar_t buffer[MAX_PATH]; вместо LPWSTR buffer;
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.09.2013, 14:03     Как правильно использовать GetModuleFileName?
Посмотрите здесь:

Как правильно вызвать метод в С++ и как использовать команду goto в default C++
Как правильно впихнуть и использовать перечисления в структуре? C++
C++ Как правильно использовать несколько файлов
C++ Как правильно использовать map?
C++ Как правильно использовать классы? Как вывести значение класса на экран?
Как правильно использовать cin.get? C++
C++ Как правильно использовать библиотеку курсес на линуксе
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kidasov
77 / 77 / 12
Регистрация: 02.12.2011
Сообщений: 966
Записей в блоге: 3
13.09.2013, 14:16     Как правильно использовать GetModuleFileName? #2
C++
1
2
3
4
5
6
7
8
9
#include <windows.h>
 
WCHAR buffer[MAX_PATH];
 
int main() {
    GetModuleFileName(NULL, buffer, sizeof(buffer) / sizeof(buffer[0]));
    printf("Filepath: %ws\n", buffer);
    return 0;
}
Вот как-то так
Убежденный
Системный программист
 Аватар для Убежденный
14639 / 6600 / 1045
Регистрация: 02.05.2013
Сообщений: 10,873
Завершенные тесты: 1
13.09.2013, 15:00     Как правильно использовать GetModuleFileName? #3
Цитата Сообщение от Limb0 Посмотреть сообщение
Уже нашел ответ, нужно было просто написать wchar_t buffer[MAX_PATH]; вместо LPWSTR buffer;
Длина файлового пути, возвращаемого GetModuleFileName, может быть намного больше MAX_PATH (260).
z668
25 / 25 / 2
Регистрация: 24.03.2013
Сообщений: 239
13.03.2015, 21:04     Как правильно использовать GetModuleFileName? #4
Как же тогда корректно получить размер буфера под путь в чистом си? Или никак? Просто задавать больший размер, например 2048?
Mistik
19 / 19 / 5
Регистрация: 25.02.2015
Сообщений: 138
13.03.2015, 21:06     Как правильно использовать GetModuleFileName? #5
Цитата Сообщение от z668 Посмотреть сообщение
Как же тогда корректно получить размер буфера?
укажите размер буффера больше чем 260.
Убежденный
Системный программист
 Аватар для Убежденный
14639 / 6600 / 1045
Регистрация: 02.05.2013
Сообщений: 10,873
Завершенные тесты: 1
13.03.2015, 21:07     Как правильно использовать GetModuleFileName? #6
В Windows максимальная длина файлового пути примерно равна 32K символам.
Что мешает сразу выделить буфер с запасом ?
castaway
Эксперт С++
4870 / 3009 / 370
Регистрация: 10.11.2010
Сообщений: 11,059
Записей в блоге: 10
Завершенные тесты: 1
13.03.2015, 21:55     Как правильно использовать GetModuleFileName? #7
Если подойти к этому ответственно, то это будет выглядеть примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <windows.h>
#include <cstdio>
 
char * get_module_file_name( HMODULE hModule = NULL ) {
    size_t size = 1;
    char * buffer;
    for ( ; ; ) {
        buffer = new char [size + 1];
        DWORD r = GetModuleFileName( hModule, buffer, size );
        if ( r < size && r != 0 ) break;
        if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
            delete buffer;
            size += 64;
        } else return NULL;
    }
    return buffer;
}
 
int main()
{
    char * mod_name = get_module_file_name();
    if ( mod_name ) {
        printf( "%s\n", mod_name );
    } else {
        printf( "get_module_file_name(): error\n" );
    }
    return 0;
}
lod
0 / 0 / 0
Регистрация: 23.02.2016
Сообщений: 1
18.01.2017, 19:21     Как правильно использовать GetModuleFileName? #8
Позволю себе слегка усовершенствовать ваш пример

Если длина пути окажется например 2048 символов, то для его получения потребуется 32 вызова GetModuleFileName, поэтому лучше на каждой итерации удваивать буфер, а не удлинять на 64 символа, тогда хватит 11 вызовов. Также целесообразнее будет начать не с единичной длины а скажем с тех же 64 символов, это позволит сэкономить ещё 6 вызовов.

Наверно, в данном случае это ни на что не влияет, но лично мне спокойнее то что выделено через new[] освобождать через delete[].

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <windows.h>
#include <cstdio>
 
char * get_module_file_name( HMODULE hModule = NULL ) {
    size_t size = 64;
    char * buffer;
    for ( ; ; ) {
        buffer = new char [size + 1];
        DWORD r = GetModuleFileName( hModule, buffer, size );
        if ( r < size && r != 0 ) break;
        if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
            delete[] buffer;
            size *= 2;
        } else return NULL;
    }
    return buffer;
}
 
int main()
{
    char * mod_name = get_module_file_name();
    if ( mod_name ) {
        printf( "%s\n", mod_name );
    } else {
        printf( "get_module_file_name(): error\n" );
    }
    delete[] mod_name;
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.01.2017, 21:55     Как правильно использовать GetModuleFileName?
Еще ссылки по теме:

C++ Как правильно использовать цикл?
C++ Раздельная компиляция и шаблоны: как правильно использовать?
C++ Как узнать имя проекта dll без использования GetModuleFileName?
Как правильно использовать struct? C++
C++ Как правильно использовать thread?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Убежденный
Системный программист
 Аватар для Убежденный
14639 / 6600 / 1045
Регистрация: 02.05.2013
Сообщений: 10,873
Завершенные тесты: 1
18.01.2017, 21:55     Как правильно использовать GetModuleFileName? #9
Цитата Сообщение от lod Посмотреть сообщение
Также целесообразнее будет начать не с единичной длины а скажем с тех же 64 символов, это позволит сэкономить ещё 6 вызовов.
Может быть, целесообразнее сразу выделить достаточно большой буфер (например, 32К символов),
чтобы ограничиться одним вызовом?
Yandex
Объявления
18.01.2017, 21:55     Как правильно использовать GetModuleFileName?
Ответ Создать тему
Опции темы

Текущее время: 09:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru