реклама на сайте
подробности

 
 
> Заголовочные файлы и модули., Как правильно?
Smoky
сообщение Dec 30 2017, 17:11
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 401
Регистрация: 7-05-10
Из: Оренбург
Пользователь №: 57 135



Добрый день. Всегда размещал специфические функции в заголовочных файлах .h. Но вот знающие люди предлагают в заголовочных файлах только объявлять переменные и функции а сами функции размещать в отдельном модуле с расширением .с. Сделал я такую попытку и компилятор сразу же потерял эти функции. В модуле и в основном файле проекта строка #include на заголовочный файл .h была объявлена. Как правильно поступать в таком случае и стоит ли это делать?


--------------------
Лень, оттвори дверь, сгоришь - а хоть и сгорю, но не оттворю.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sigmaN
сообщение Jan 1 2018, 12:45
Сообщение #2


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Так вы логики в .h файлах не видите потому не понимаете процесс компиляции и сборки проекта.

В Си вам можно обойтись и без .h файлов, но не наоборот. Так вот то то вы делаете - это такой извращенный способ сформирвать один большой .с файл.
Препроцессор же вместо #include "header.h" просто вставляет текст из файла header.h. Ни больше ни меньше. Вы щас получаете большой .c файл, который отправляется на копиляцию.

По-пробую как-то сжато передать суть...
Для упрощения пока не рассматриваем данные и скажем, что по сути каждый .c файл это тупо набор функций - кусков исполняемого кода который можно вызвать по имени.
Для того чтобы вызвать этот кусок кода надо знать имя, типы возвращаемого функцией значения и типы аргументов функции(плюс их кол-во).
В общем случае мы имеем несколько .с файлов, которые вызывают функции друг друга.
Но компиляция этих файлов происходит независимо!
Допустим, у вас в проекте три .с файла. 1.с 2.с 3.с Это будет означать, что надо ТРИ раза вызвать компилятор и на выходе мы получим три объектных модуля 1.obj 2.obj 3.obj
Эти объектные модули - полуфабрикаты, в которых указано имя функции и исполняемый код ей соответствующий. Данные мы пока не рассматриваем, как я уже и говорил.

Вы же помните да, что чтобы вызвать функцию надо знать её имя, тип результата и аргументов? Это необходимо чтобы сгенерировать код вызова этой фнкции.
Так вот это и есть тот самый прототип функции.
Мы в файле 1.с хотим использовать фукнцию void func(int a); которая реализована в файле 2.с и магия в том, что нам для этого нужно знать только прототип функции.
Помните же да, что компилятор компилирует один .с файл за один раз. Может быть файл 1.с поступил на компиляцию раньше и машинного кода для 2.с еще вовсе нет! Это не проблема, нам достаточно прототипа функции. Дальше линкер разберется.. Но об этом позднее.

Так вот мы могли бы в файле 1.с ПЕРЕД вызовом func(1); объявить её прототип. Написать void func(int a);
Тогда не возникнет никаких проблем и компилятор будет знать что func(1) соответствует прототипу и сможет с генерировать машинный код для вызова. Как видите, никаких #include и .h файлов вообще не нужно!

Однако это очень неудобно, потому что функция func() может потребоваться нам и в файле 1.с и в файле 10.с и еще в многих местах! Копипаситить прототипы теперь везде? Было бы глупо.
Выход простой: Функция func() реализована в файле 2.с, поэтому очень логично сделать файл 2.h и поместить туда прототипы всех функций реализованных в файле 2.с.

Теперь любой .с файл, который хочет использовать функции реализованные в 2.с просто делает #include 2.h и таким образом в начале этого .с файла препроцессор подставляет все прототипы всех функций из файла 2.с и мы можем свободно их вызывать из любых других .с файлов. Прототипы теперь описаны один раз и хранятся централизовано. Этот файл еще называют интерфейсом модуля. В этом-же .h файле могут хранится описания типов данных, но этого мы пока не касаемся для упрощения понимания.


Также стоит отметить, что нет такого понятия как "основной .с файл проекта", которое вы тут используете.
Есть просто требование, что где-то должна обязательная быть функция main(), которая будет вызвана из стартапа, после того как будет подготовлено Си окружение(инициализирована память, указатель стека и т.д.)



Короче после того как компилятор был вызван 100500 раз, ОТДЕЛЬНО для каждого .с файла и на выходе получены .obj файлы
https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%...%83%D0%BB%D1%8C
Начинается компоновка(линкинг) вызывается линкер, которому скармливаются все эти объектные модули(и не только, но это щас не важно).
Линкер размещает каждый .obj файл по определенному адресу и таким образом знает какая функция из какого .obj расположена по какому адресу в памяти.
Я сейчас намеренно всё очень упрощаю и не касаюсь темы данных, секци и т.д...

Далее линкер проходится по всем вызовам функций и заменяет вызов по имени на конкретный адрес! Ведь он теперь знает адреса всех функций из всех .obj файлов.
Например 1.obj вызывается функция func(). Линкер находит ее реализацию в модуле 2.obj и в то место подставляет уже АДРЕС. Либо выдаст ошибку если нигде ни в одном из .obj которые ему передали он эту функкцию не нашел. Либо если в двух разных .obj есть две функции с одинаковым именем.



Так вот вы разделите свой проект исходя из вышеописанной логики и обязательно добавьте все свои .c файлы в проект.
IDE AVRStudio для вас сделает всю магию - т.е. будет вызывать компилятор отдельно для каждого .c файла, потом все полученные результаты передаст линкеру и на выходе у вас получится один исполняемый файл. Это всё произойдет автоматически.

Во всем этом разделении есть очень много логики и смысла, я лишь ОЧЕНЬ упрощенно показал вам процесс.
Без дальнейшего изучения тут не обойтись. Есть static функции которые из других .c файлов вызвать нельзя. Есть inline функции которые вместо вызова сразу встраиваются в точку вызова... Есть много тонкостей разных которые требуют отдельного освещения и имеют свои тонкости.

С Новым Годом всех, успехов в разработках и изучении Си )))


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Smoky   Заголовочные файлы и модули.   Dec 30 2017, 17:11
- - sigmaN   Думаю что эти функции потерял не компилятор, а лин...   Dec 30 2017, 20:01
|- - Smoky   Цитата(sigmaN @ Dec 31 2017, 02:01) Думаю...   Dec 31 2017, 06:39
- - Baser   Пару раз встречал расположение функций в файлах .h...   Dec 30 2017, 22:52
- - dxp   Помещение определений встраиваемых функций (inline...   Dec 31 2017, 10:21
|- - gosha-z   Цитата(dxp @ Dec 31 2017, 13:21) Помещени...   Dec 31 2017, 12:54
|- - Сергей Борщ   QUOTE (gosha-z @ Dec 31 2017, 14:54)...   Dec 31 2017, 16:33
|- - gosha-z   Цитата(Сергей Борщ @ Dec 31 2017, 19:33) ...   Dec 31 2017, 19:00
- - Smoky   Разобрав несколько примеров сделал попытку передел...   Jan 1 2018, 05:55
|- - HardEgor   Цитата(Smoky @ Jan 1 2018, 12:55) Разобра...   Jan 1 2018, 07:42
|- - Smoky   Цитата(HardEgor @ Jan 1 2018, 13:42) Лучш...   Jan 1 2018, 07:55
|- - nice_vladi   Цитата(sigmaN @ Jan 1 2018, 12:45) ... П...   Jan 1 2018, 13:45
|- - Smoky   Цитата(sigmaN @ Jan 1 2018, 18:45) Так вы...   Jan 1 2018, 14:54
|- - sigmaN   Цитата(Smoky @ Jan 1 2018, 17:54) Логику ...   Jan 1 2018, 18:38
- - Baser   Цитата(Smoky @ Jan 1 2018, 07:55) Разобра...   Jan 1 2018, 18:47
|- - Smoky   Цитата(Baser @ Jan 2 2018, 00:47) Передел...   Jan 1 2018, 19:40
|- - Baser   Цитата(Smoky @ Jan 1 2018, 21:40) Прошу п...   Jan 1 2018, 20:30
|- - Smoky   Цитата(Baser @ Jan 2 2018, 02:30) Студии ...   Jan 2 2018, 17:11
|- - Baser   Цитата(Smoky @ Jan 2 2018, 19:11) Предлаг...   Jan 2 2018, 19:18
- - sigmaN   Мне пришлось импортировать проект в AS 7 Я правил...   Jan 1 2018, 20:01
|- - Dog Pawlowa   Цитата(sigmaN @ Jan 1 2018, 23:01) ... Си...   Jan 1 2018, 21:10
- - ArtemKAD   В хидеры включены переменные(и константные перемен...   Jan 1 2018, 20:10
- - sigmaN   ЦитатаПервый способ создаст две переменных, ошибок...   Jan 1 2018, 21:24
- - sigmaN   ЦитатаКоллеги, вы "ломаете" все мои уста...   Jan 2 2018, 21:30
|- - Smoky   Цитата(sigmaN @ Jan 3 2018, 03:30) Вам бы...   Jan 3 2018, 08:00
- - Владивольт   похожая тема - взгляните   Jan 3 2018, 17:39
- - Smoky   Моя благодарность "волхвам" за науку, вс...   Jan 10 2018, 17:06
- - sigmaN   Обращайтесь, я по умничать всегда рад   Jan 10 2018, 18:44
- - Unfog   Для исключения повторной компиляции содержимого h-...   Jan 12 2018, 06:13
- - Smoky   Цитата(Unfog @ Jan 12 2018, 12:13) Для ис...   Jan 12 2018, 06:49
- - Grizzzly   Цитата(Smoky @ Jan 12 2018, 09:49) А это ...   Jan 12 2018, 07:04
|- - Smoky   Цитата(Grizzzly @ Jan 12 2018, 13:04) Ну ...   Jan 12 2018, 10:49
- - Kabdim   Цитата(Smoky @ Jan 12 2018, 09:49) А это ...   Jan 12 2018, 08:21
- - Baser   Цитата(Kabdim @ Jan 12 2018, 10:21) Насто...   Jan 12 2018, 10:29
- - aiwa   Цитата(Kabdim @ Jan 12 2018, 10:21) Насто...   Jan 13 2018, 07:51


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 9th August 2025 - 07:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01402 секунд с 7
ELECTRONIX ©2004-2016