Написание библиотек, использующих библиотеки, которые используются в скетче

Я знаю, что название немного тупое, но позвольте мне попытаться объяснить: Я пытаюсь создать библиотеку простых функций для использования с моей TFT-панелью.

В панели есть включаемый файл (#include "SSD1306Wire.h")

У меня есть эскиз, и в эскизе есть ссылка на указанный выше файл #include Я также хочу использовать свою библиотеку tftHelper.h, но эта библиотека также должна ссылаться на SSD1306Wire.h, чтобы вспомогательные функции работали.

Есть ли способ сослаться на SSD1306Wire.h один раз и иметь возможность использовать ссылку в функциях моей вспомогательной библиотеки?

Я думаю, что еще важнее, как правильно поступить в такой ситуации?

, 👍3


2 ответа


8

Правильный способ справиться с этим — добавить #include guard в заголовочный файл, чтобы предотвратить включение содержимого более одного раза.

В заголовочном файле filename.h вы должны добавить что-то вроде этого:

#ifndef _FILENAME_H_
#define _FILENAME_H_

// Здесь ваш код заголовка

#endif /* _FILENAME_H_ */

Блок #ifndef не позволит коду быть включенным более одного раза. Лучше всего всегда помещать защитные элементы включения в заголовочные файлы.

,

0

Библиотека не имеет возможности узнать, что находится в вашем эскизе. Эти две вещи полностью разделены, и нет способа преодолеть этот разрыв.

Вы не можете включить библиотеку A в эскиз и ожидать, что библиотека B узнает об этом. Библиотека B должна явно включать в себя библиотеку A, чтобы библиотека B вообще имела представление о том, что такое библиотека A.

Включение библиотеки состоит из двух важных частей. Оно не только сообщает единице перевода, что вы включаете ее в то, что есть в библиотеке, но и сообщает IDE, что вы хотите использовать эту библиотеку и скомпилировать для нее исходный код.

Видите ли, библиотека обычно содержит две отдельные вещи — заголовочный файл (или несколько заголовочных файлов) и файлы исходного кода. Заголовочный файл описывает библиотеку — какие классы она имеет, какие экспортированные функции или переменные и т. д. Исходный код реализует библиотеку. Когда вы включаете библиотеку, он просто вставляет это определение библиотеки (заголовочный файл) в ваш исходный код в точке #include. Так же, как копировать-вставить.

IDE делает немного дополнительной магии и связывает этот файл заголовка с каталогом, в котором есть другие файлы. Затем он находит файлы исходного кода в этом месте и компилирует их.

Каждый компилируемый файл компилируется отдельно. Это называется единицей перевода (TU), и каждая из них полностью отделена от всех остальных. Никто не может знать, что есть в любом другом файле, если только вы явно не скажете этому файлу найти что-то где-то еще (хотя вы не скажете ему где, а только то, что это «существует где-то еще»). И именно это делают заголовочные файлы — они сообщают единицам перевода, какие вещи доступны в другом месте.

Так что если TU A нужен ресурс F, ему нужно об этом сказать. Если TU B нужен ресурс F, ему тоже нужно об этом сказать.

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

,