Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
5 / 5 / 4
Регистрация: 31.12.2008
Сообщений: 86

Глобальный HINSTANCE для всего проекта

17.10.2014, 00:24. Показов 2203. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Помогите решить проблему Думаю, по ходу решения всплывет мое непонимание какого-то аспекта структуры программы, по этому поводу тоже прошу меня просвятить.

Итак, сейчас все работает. Проект состоит из нескольких файлов с исходниками и одного хидера (main.h), содержащего описания классов, прототипы функций, нужные подключаемые библиотеки итд.
Файл с функцией main (main.cpp) сильно перегружен: там находятся обработчики сообщений для всех диалоговых окон, конструкторы некоторых интерфейсных классов и прочий мусор. Задача - разделить все это для удобства по нескольким файлам.
Сейчас, в самом начале main.cpp, у меня красуется
C++
1
2
3
4
5
#include "resource.h"
#include "controls.h"
#include "main.h"
 
HINSTANCE hInst = 0;
Соответственно, hInst виден только в пределах main.cpp. Некоторые из функций, которые нужно перенести из main.cpp в другой файл, используют hInst. Следовательно, нужно сделать этот дескриптор видимым для них. Самым простым вариантом мне показалось перенести его объявление в main.h. Но не тут-то было.
Сейчас main.h выглядит так:

C++
1
2
3
4
5
6
7
8
9
#ifndef _MAIN_H_INCLUDED
#define _MAIN_H_INCLUDED
 
#include <windows.h>
....
//далее подключение прочих хидеров, описание классов итд
...
 
#endif // _MAIN_H_INCLUDED
В каждом сорс-файле в проекте в самом начале написано #include main.h

Так вот, если просто целиком скопировать
C++
1
HINSTANCE hInst = 0;
в main.h, при компиляции получаем ошибку: error LNK2005: "struct HINSTANCE__ * hInst" (?hInst@@3PAUHINSTANCE__@@A) already defined in command.obj. Ошибка вылезает 5 раз, по числу cpp-файлов в проекте.
Если запихнуть объявление HINSTANCE hInst в main.h, а в main.cpp на том же месте написать hInst = 0, ошибки вылетают следующие: error C4430: missing type specifier - int assumed. Note: C++ does not support default-int И error C2040: 'hInst' : 'int' differs in levels of indirection from 'HINSTANCE'.

Научите, в чем проблема, пожалуйста
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.10.2014, 00:24
Ответы с готовыми решениями:

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

Константы для всего проекта
Здравствуйте. Можно ли как нить объявить константы для всего проекта,не в классе. Или vb.net так нельзя? чистый ООП?

Переменные для всего проекта
Делаю приложение на основе БД! Несколько форм этого приложения работают с одними и теми же данными из этой базы. Хотелось бы при запуске...

12
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
17.10.2014, 00:37
Лучший ответ Сообщение было отмечено yeng как решение

Решение

во все файлы,кроме одного напиши так
C
1
extern HINSTANCE hInst;
extern даст понять компилятору что переменная где то объявлена не в этом файле

Добавлено через 3 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
во все файлы,кроме одного напиши так
чтобы не пихать в каждый файл
можно написать в main.h
C++
1
extern HINSTANCE hInst;
а в main.cpp
C++
1
HINSTANCE hInst = 0;
кстати можно написать и так
C++
1
HINSTANCE hInst;
глобальные переменные обнуляются автоматически
1
5 / 5 / 4
Регистрация: 31.12.2008
Сообщений: 86
17.10.2014, 00:41  [ТС]
ValeryS, спасибо, завтра попробую. А вообще структура программы, как у меня, является рациональной? Один толстый хидер с описанием классов и прототипами, подключаемый к каждому из исходников, содержащих тела классов и тела функций? Или у людей по-другому это делается?

Добавлено через 2 минуты
И прошу прощения, что сперва написал, а потом подумал. Сейчас представил себе, как здесь будет работать ifndef-define, и понял, что мой вариант с HINSTANCE hInst = 0 внутри хидера был в корне неправильным Это к предложенному варианту, а вопрос выше все еще актуален.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
17.10.2014, 00:44
Цитата Сообщение от yeng Посмотреть сообщение
Один толстый хидер с описанием классов и прототипами, подключаемый к каждому из исходников,
разбей на сущности
типа каждому классу свой заголовочный файл
а в main.h можешь подключить нужные
0
5 / 5 / 4
Регистрация: 31.12.2008
Сообщений: 86
17.10.2014, 00:57  [ТС]
ValeryS, то есть чтобы что-то подобное получилось?



Не по теме:

Прямо в пост картинку вставить не получилось, есть вообще такая возможность?


А тогда еще один вопрос. В каждый из этих отдельных хидеров могут подключаться необходимые для их работы стандартные хидеры. То есть, например, math.h подключен и в cl1.h, и в cl2.h, а в main.h подключаются и cl1.h, и cl2.h, то есть получится, что math.h подключается 2 раза. На это, вроде бы, компилятор ругаться будет. Как с этим быть?
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
17.10.2014, 01:14
Цитата Сообщение от yeng Посмотреть сообщение
то есть получится, что math.h подключается 2 раза. На это, вроде бы, компилятор ругаться будет. Как с этим быть?
Цитата Сообщение от yeng Посмотреть сообщение
C++
1
2
3
4
#ifndef _MAIN_H_INCLUDED
#define _MAIN_H_INCLUDED
// ...
#endif // _MAIN_H_INCLUDED
Чтобы избежать подобной ситуации и определяют символ HEADERFILENAME_H_INCLUDED (или что-то подобное) или можно еще #pragma once в начале хеадер файла писать. Мой math.h:
C
1
2
3
4
5
6
#ifndef _MATH_H
#define _MATH_H 1
//
// ... math.h magic here ...
//
#endif /* math.h  */
0
5 / 5 / 4
Регистрация: 31.12.2008
Сообщений: 86
17.10.2014, 01:21  [ТС]
Цитата Сообщение от schdub Посмотреть сообщение
Чтобы избежать подобной ситуации и определяют символ HEADERFILENAME_H_INCLUDED
Все равно не понимаю.
Вот пример:

h1.h:
C++
1
2
#include <math.h>
...
h2.h
C++
1
2
#include <math.h>
...
Нам нужно подключить оба этих хидера в main.h .
Как я понял, директивы ifndef-define работают для того, чтобы один и тот же хидер не подключался несколько раз. Но ведь здесь у нас 2 разных хидера, которые ВНУТРИ себя содержат один и тот же хидер. Не понимаю.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
17.10.2014, 01:30
во первых в <math.h> уже есть обвязка исключающая двойное включение
а во вторых зачем его пихать в заголовочный файл? не проще в cpp?
0
5 / 5 / 4
Регистрация: 31.12.2008
Сообщений: 86
17.10.2014, 10:03  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
а во вторых зачем его пихать в заголовочный файл? не проще в cpp?
А если подключаемый хидер содержит какие-либо пользовательские классы, а хидер, который пишем мы, содержит прототипы функций, получающих или возвращающих объекты этих классов? Компилятор ругнется, потому что хидер не будет "знать" этих типов.
Цитата Сообщение от ValeryS Посмотреть сообщение
во первых в <math.h> уже есть обвязка исключающая двойное включение
Во всех стандартных библиотеках есть?
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
17.10.2014, 10:25
Цитата Сообщение от yeng Посмотреть сообщение
А если подключаемый хидер содержит какие-либо пользовательские классы, а хидер, который пишем мы, содержит прототипы функций,
нафантазировать можно все что угодно
для этого и существует первый этап -проектирование программы
если неправильно спроектируешь потом сам заплюхаешся
Цитата Сообщение от yeng Посмотреть сообщение
Во всех стандартных библиотеках есть?
это не библиотеки а заголовочные файлы
если написаны нормально то да
открой любой стандартный заголовок и увидишь сколько там директив условной компиляции
0
5 / 5 / 4
Регистрация: 31.12.2008
Сообщений: 86
17.10.2014, 10:42  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
нафантазировать можно все что угодно
Ну ок. Допустим, мы пишем хидер с прототипом функции string* Function (void). В cpp-файле у нас тело этой функции. Куда нам подключать хидер string.h, в таком случае? Ведь если подключить только в cpp-файле, хидер не пропустит компилятор. Подключать и там, и там? Проще в хидере подключить, не?
Я тут не в глаза долблюсь, я прошу, чтобы мне объяснили, как сделать правильно, или ткнули носом, где почитать.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
17.10.2014, 10:53
Цитата Сообщение от yeng Посмотреть сообщение
Куда нам подключать хидер string.h,
в этом случае, конечно в заголовочный


Цитата Сообщение от yeng Посмотреть сообщение
Ведь если подключить только в cpp-файле, хидер не пропустит компилятор.

может и пропустить,если напишешь так
C++
1
2
#include <string>
#include "MyHandle.h"
нужно понять как работает препроцессор встретив include
а он просто вставляет содержимое файла на место include
0
5 / 5 / 4
Регистрация: 31.12.2008
Сообщений: 86
17.10.2014, 11:05  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
а он просто вставляет содержимое файла на место include
Это я осознал. Тогда возвращаясь к предыдущему вопросу: как быть в случае подключения в "главный" хидер двух различных хидеров, в каждом из которых подключен одинаковый хидер? Вот этот пример:
Цитата Сообщение от yeng Посмотреть сообщение
То есть, например, math.h подключен и в cl1.h, и в cl2.h, а в main.h подключаются и cl1.h, и cl2.h
Забить на всё и подключать, уповая на
Цитата Сообщение от ValeryS Посмотреть сообщение
открой любой стандартный заголовок и увидишь сколько там директив условной компиляции
, так обычно делают? Соответственно, когда пишут свой хидер, тоже активно директивы пишут?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.10.2014, 11:05
Помогаю со студенческими работами здесь

Обработчик ошибок для всего проекта
Как создать обработчик ошибок для всего проекта? Ну, то есть, можно создать спецальную форму, которая будет выскакивать при возникновении...

Глобальные переменные для всего проекта
У меня есть проект, в нем несколько питоновских файлов. Есть питоновский файл, в котором есть глобальные переменные для всего проекта. Мне...

Диаграмма классов для всего проекта
Проект состоит из нескольких решений эти решения взаимодействуют между собой можно ли построить автоматически диаграмму классов со...

Объявление глобальных переменных для всего проекта
Подскажите как объявить переменные, так чтобы они были глобальными для всего проекта, т.е. для всех модулей: Unit1, Unit2 и т.д.

Задать стиль текста для всего проекта C#
VS 2010 С#. Можно ли задать определённый шрифт для всех компонентов на форме в проекте?


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru