В моем текущем проекте я работаю с интерфейсом arpackpp. Вся библиотека написана на .h
файлы, так что нет необходимости компилировать библиотеку. Проблема, с которой я сталкиваюсь сейчас — когда я включаю некоторые из arpackpp
заголовочные файлы в некоторых моих файлах, которые не являются main.cpp
Я получаю следующие ошибки:
/…/Files/Include/../../../arpack++/include/arerror.h:163: множественное определение
ArpackError::Set(ArpackError::ErrorCode, std::string const&)'
std :: iterator_traits :: iterator_category std :: __ iterator_category (char * const&) ‘:
/.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here
/tmp/ccruWhMn.o: In function
/…/Files/Include/../../../arpack++/include/arerror.h:163: множественное определениеArpackError::code'
std :: vector> :: max_size () const ‘:
/.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here
/tmp/ccruWhMn.o: In function
для нескольких arpackpp
функции при связывании всех .o
файлы. Как я прочитал в нескольких потоках, проблема в том, что я фактически включаю создание экземпляров функций, которых обычно следует избегать.
Поскольку я не хочу менять всю библиотеку, я включил все классы и функции, используя arpackpp
занятия в main.cpp
, который становится довольно грязным. Есть ли решение этой проблемы? И почему не включают охранников (#ifndef...#endif)
предотвратить эту проблему?
В общем, самый простой способ работы с библиотеками только с заголовками — это расширение вашего кода только с помощью заголовков. Если вы используете правильные средства защиты заголовков, это устранит проблему множественных определений вашего кода. Если у вас есть большая база существующего кода, я бы предложил переименовать все ваши *.cpp
файлы в *.hpp
(заголовочные файлы c ++), а затем добавьте подходящие охранники заголовков. Кроме того, удобный способ обработки этого кода базы — создать дополнительный заголовочный файл. config.hpp
и включите все остальные заголовки в этот файл. Тогда в вашем main.c просто включите config.hpp
файл.
например
// Config.hpp ------------------------------------------------=
#include "example.hpp"#include "example1.hpp"#include "example2.hpp"// etc.
// main.cpp --------------------------------------------------=
#include "Config.hpp"
int main() {
// Your code here.
return 0;
}
Кроме того, если вы хотите продолжить работу над структурой проекта, было бы просто разделить весь код на функции, необходимые для доступа arpackcpp
непосредственно. Затем включите их всех в один *.cpp
файл и скомпилировать в *.o
и ссылка.
Прежде всего, включенные средства защиты не помогают в этом пункте, поскольку они только предотвращают множественные включения заголовка в «поддерево» графа зависимостей файлов вашего проекта. Другими словами: если вы включите заголовок в два полностью разделенных файла одного и того же проекта, препроцессор c ++ заменит #include <header.h>
дважды и независимо по коду, указанному в шапке. Это прекрасно, если заголовок содержит только объявления.
В вашем случае (и в случае многих других библиотек только для заголовков) определения также содержатся в заголовках. Так что, к сожалению (насколько я знаю), нет другого элегантного способа, кроме как включить файлы, содержащие определения, один раз в ваш проект. https://github.com/m-reuter/arpackpp/blob/master/include/README явно указывает, какие файлы содержат определения.
Однако некоторые библиотеки предоставляют макросы препроцессора, чтобы инициировать включение определений для предоставленных заголовочных файлов (например, https://github.com/nothings/stb). Может быть arpackpp
предоставляет аналогичные механизмы.