как запретить другим разработчикам включать сторонний заголовок в C ++ - PullRequest
2 голосов
/ 13 октября 2011

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

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

Например, если они делают что-то вроде этого:

#include "cool_library.h"

они получают сообщение об ошибке:

do not include directly cool_library.h, instead use the cool_library_wrapper class

это возможно? Я использую GNU GCC

Ответы [ 5 ]

3 голосов
/ 13 октября 2011

Поскольку вы используете gcc, вы можете использовать функцию препроцессора #include_next: создать заголовок с тем же именем, что и у третьей стороны, в каталоге, который будет иметь более высокий приоритет при поиске файлов заголовков. В вашей версии заголовка используйте что-то вроде

#if WRAPPER_HEADER_HAS_BEEN_INCLUDED
#  include_next <cool_library.h>
#else
#  error ...
#endif
3 голосов
/ 13 октября 2011

Вы можете использовать директиву препроцессора #error в блоке #ifndef.

Например, в оригинальном файле .h есть:

#ifndef COOL_LIBRARY_WRAPPER_CLASS_INCLUDED
#error "do not include this file directly
#endif

И в заголовочном файле класса-обёртки сделать это:

#define COOL_LIBRARY_WRAPPER_CLASS_INCLUDED
2 голосов
/ 13 октября 2011

Это возможно только в том случае, если вы согласны с изменением файла cool_library.h. Вы можете сделать что-то вроде:

cool_library.h

#ifndef INCLUDED_FROM_COOL_LIBRARY_WRAPPER
#error do not include directly cool_library.h, instead use the cool_library_wrapper class
#endif

.. remainder of original cool_library.h

cool_library_wrapper.h

#define INCLUDED_FROM_COOL_LIBRARY_WRAPPER
#include "cool_library.h"

... your wrapper

#undef INCLUDED_FROM_COOL_LIBRARY_WRAPPER

Конечно, вы все еще не можете помешать вашим коллегам определить INCLUDED_FROM_COOL_LIBRARY_WRAPPER сами, включая исходный заголовочный файл. Это социальная проблема, которая не имеет технического решения.

1 голос
/ 13 октября 2011

Не помещайте <cool_library.h> в обычный путь включения сборки. Вы можете использовать специальный CFLAGS для своей оболочки, чтобы предоставить ему доступ, или получить к нему доступ с более явным путем, например <vendor/xyz/cool_library.h>, из некоторого пути включения более высокого уровня.

Другим подходом, основанным на пути, было бы поместить локальный <cool_library.h> ранее в путь включения и использовать подход #ifdef/#error, описанный выше. Если присутствует магическое определение, тогда заглушка заглушки может использовать более явный путь, чтобы подобрать настоящий заголовок. (Некоторые компиляторы имеют хак для продолжения пути поиска, если вы включили что-то с именем, точно совпадающим с заголовком, который читается)

1 голос
/ 13 октября 2011

Если вы обычно используете заголовки для всего проекта, вы можете проверить наличие включаемого защитного заголовка из стороннего заголовка, например,

// third_party.h
#ifndef THIRD_PARTY_H
#define THIRD_PARTY_H
...

и

// your_project_wide.h
...
#ifdef THIRD_PARTY_H
#warning "Please include "cool_library.h"
#endif
...

Здесь предостережения: #warning является расширением gcc, и все это зависит от внешних зависимостей, включаемых перед заголовками вашего проекта (, что вы, возможно, не захотите делать ).

...