Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как сделать параметр одной функции видимым для остальных функций?

28K
05 мая 2008 года
Tirpitz
32 / / 05.05.2008
У функции WinMain есть параметр hInstance. Значение этого параметра иногда нужно использовать в других функция этого же файла. Естественно, самый простой способ - создать глобальную переменную того же типа но с другим именем и присвоить ей значение параметра hInstance. Вот только не хочется плодить переменные.
В языке C++ можно создать глобальную переменную с тем же именем (hInstance) и потом внутри функции WinMain с помощью оператора разрешения контекста присвоить глобальной переменной hInstance значение параметра hInstance функции WinMain:
 
Код:
::hInstance = hInstance

А как быть в языке C, в котором пространства имен нет?
25K
05 мая 2008 года
San_
42 / / 03.10.2007
ты сам себе противоречишь
то ты: "Вот только не хочется плодить переменные" и тут же создаешь ее
а что мешает передавать эту переменную в нужную функцию ?
28K
05 мая 2008 года
Tirpitz
32 / / 05.05.2008
Пример с глобальной переменной, имеющей то же имя, что и локальная переменная, - это просто попытка если и не обойтись совсем без дополнительных переменных, то хотя бы использовать везде одно и то же имя. Но ведь на то и язык C, чтобы с его помощью можно было сделать все что угодно. Вопрос только в том, как?
353
05 мая 2008 года
Nixus
840 / / 04.01.2007
Переименовать локальную переменную в WinMain:
 
Код:
INT WINAPI WinMain(HINSTANCE hInst, ...)
{
      hInstance = hInst;
      // ...
}
28K
05 мая 2008 года
Tirpitz
32 / / 05.05.2008
Тогда уже можно объявить глобальный указатель на тип HINSTANCE, а потом в теле функции WinMain присвоить ему адрес параметра hInstance. В общем случае так делать, наверное, и неправильно, но ведь выполнение программы начинается и заканчивается в функции WinMain, и, следовательно, ее локальные переменные никуда не исчезают и остаются на протяжение всего времени выполнения программы по тем же адресам.

Код:
void MyFunc(HINSTANCE hInstance);

HINSTANCE * phInstance;

INT WINAPI WinMain(HINSTANCE hInstance, ...)
{
   phInstance = &hInstance;
   ...
}

void foo()
{
   MyFunc(*phInstance);
   ...
}
353
05 мая 2008 года
Nixus
840 / / 04.01.2007
Цитата: Tirpitz
Тогда уже можно объявить глобальный указатель на тип HINSTANCE, а потом в теле функции WinMain присвоить ему адрес параметра hInstance. В общем случае так делать, наверное, и неправильно, но ведь выполнение программы начинается и заканчивается в функции WinMain, и, следовательно, ее локальные переменные никуда не исчезают и остаются на протяжение всего времени выполнения программы по тем же адресам.



А теперь сравни:

 
Код:
void MyFunc(HINSTANCE hInstance);

HINSTANCE * phInstance;

INT WINAPI WinMain(HINSTANCE hInstance, ...)
{
   phInstance = &hInstance;
   ...
   MyFunc(*phInstance);
}

и
 
Код:
void MyFunc(HINSTANCE hInstance);

HINSTANCE hInstance;

INT WINAPI WinMain(HINSTANCE hInst, ...)
{
      hInstance = hInst;
      // ...
      MyFunc(hInstance);
}

Какой код понятнее и короче?
562
05 мая 2008 года
tarekon
175 / / 19.08.2003
Цитата: Tirpitz
Тогда уже можно объявить глобальный указатель на тип HINSTANCE, а потом в теле функции WinMain присвоить ему адрес параметра hInstance. В общем случае так делать, наверное, и неправильно, но ведь выполнение программы начинается и заканчивается в функции WinMain, и, следовательно, ее локальные переменные никуда не исчезают и остаются на протяжение всего времени выполнения программы по тем же адресам.



Ай-ай-ай, а как же конструкторы/деструкторы глобальных объектов? Или, если говорить про язык C, то функции, переданные в atexit()? Они же не смогут проконтролировать, когда и откуда их вызвали. Может получиться гейзенбаг :)

Вообще ради hInstance такое городить не стоит. Всегда же можно вызвать GetModuleHandle( 0 ).

28K
06 мая 2008 года
Tirpitz
32 / / 05.05.2008
Насчет того, "Какой код понятнее и короче?", то, конечно, и понятнее, и короче, и надежнее просто использовать дополнительную переменную hInst.

И большое спасибо, tarekon, за GetModuleHandle(). В который раз убедился, что где-то в недрах WinAPI непременно есть та самая функция, которая нужна в данном случае.
353
06 мая 2008 года
Nixus
840 / / 04.01.2007
Цитата: Tirpitz
Насчет того, "Какой код понятнее и короче?", то, конечно, и понятнее, и короче, и надежнее просто использовать дополнительную переменную hInst.


Интересно, где это я ввожу дополнительную переменную в сравнении с другим кодом? Ты называешь переименование параметра функции вводом дополнительной переменной?

28K
06 мая 2008 года
Tirpitz
32 / / 05.05.2008
Nixus, дополнительной переменной я считаю глобальную переменную hInstance в примере:
 
Код:
HINSTANCE hInstance;

INT WINAPI WinMain(HINSTANCE hInst, ...)
{
     hInstance = hInst;
     ...
}

Просто изначально интересно было, можно ли сделать параметр hInst (локальную для функции WinMain переменную) видимым для других функций в этом же файле. Без введения любых других переменных.
353
06 мая 2008 года
Nixus
840 / / 04.01.2007
Смотрим первое сообщение:
 
Код:
::hInstance = hInstance

Ты думаешь этот код будет работать без дополнительной переменной?

Ну и конечно куда проще везде писать GetModuleHandle(0), чем hInstance.
28K
06 мая 2008 года
Tirpitz
32 / / 05.05.2008
Nixus, я вовсе не думаю, что "::hInstance = hInstance" "будет работать без дополнительной переменной". Повторю свои слова из второго сообщения:
Цитата:
... это просто попытка если и не обойтись совсем без дополнительных переменных, то хотя бы использовать везде одно и то же имя.


Кроме того, я же безо всякой иронии согласился, что:

Цитата:
... и понятнее, и короче, и надежнее просто использовать дополнительную переменную hInst.


А насчет GetModuleHandle() - я, например, не знал, что можно получить значение hInstance иначе, кроме как из передаваемого в функцию WinMain параметра. Не знаю как насчет производительности, но в данном конкретном случае эта функция действительно заменяет создание новой глобальной перменной :)

3
06 мая 2008 года
Green
4.8K / / 20.01.2000
Будь внимателен!
GetModuleHandle(NULL) возвращает хендл (базовый адрес) модуля первым загруженный в процесс (т.е. основного модуля, обычно это хендл образа запущенного EXE), а не хендл модуля из которого происходит вызов ф-ции GetModuleHandle.
Т.е. если ты вызовешь GetModuleHandle(NULL) из кода DLL (или другого неосновного модуля), то получишь хендл не этой DLL, а на основного модуля.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог