множественное определение использования arpackpp

в моем текущем проекте я работаю с интерфейсом arpackpp. Вся библиотека написана в .h файлах, поэтому нет необходимости компилировать библиотеку. Проблема, с которой я столкнулся сейчас, - когда я включаю некоторые из файлов заголовков arpackpp в некоторые из моих файлов, которые не являются main.cpp, я получаю следующие ошибки:

/.../Files/Includes/../../../arpack++/include/arerror.h:163: множественное определение ArpackError::Set(ArpackError::ErrorCode, std::string const&)' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In functionstd :: iterator_traits :: iterator_category std :: __ iterator_category (char * const &) ': / ... / Files / Includes /../../../ arpack ++ / include / arerror.h: 163: множественное определение ArpackError::code' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In functionstd :: vector> :: max_size () const ':

для нескольких arpackpp функций при связывании всех .o файлов. Поскольку я читал в нескольких темах, проблема в том, что я фактически включаю создание экземпляров функций, чего обычно следует избегать. Поскольку я не хочу менять всю библиотеку, я включил все классы и функции, использующие arpackpp классы в main.cpp, что становится довольно запутанным. Есть ли способ решения этой проблемы? И почему не включены охранники (#ifndef...#endif), предотвращающие эту проблему?


person dimmigen    schedule 29.07.2016    source источник
comment
не могли бы вы подробнее рассказать о своих ошибках ... несколько определений ... могут означать несколько вещей? Вы можете сделать это, отредактировав свой вопрос.   -  person silvergasp    schedule 29.07.2016


Ответы (2)


В общем, самый простой способ работы с библиотеками только для заголовков - это расширить код только с помощью заголовков. При условии, что вы используете правильную защиту заголовков, это устранит проблему множественных определений вашего кода. Если у вас есть большая база существующего кода, я бы посоветовал вам переименовать все ваши *.cpp файлы в *.hpp (файлы заголовков c ++), а затем добавить подходящие средства защиты заголовков. Более того, удобный способ обработки этого кода базы - создать дополнительный файл заголовка config.hpp и включить все остальные заголовки в этот файл. Затем в ваш main.c просто включить файл config.hpp.

e.g.

// 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 и создайте ссылку.

person silvergasp    schedule 29.07.2016
comment
Спасибо за ответ. Помогло изменение моих файлов на hpp. Единственное неудобство, с которым я сталкиваюсь, заключается в том, что мой make-файл не распознает никаких шансов в моих файлах * .hpp. - person dimmigen; 02.08.2016
comment
Ваше второе предложение не сработало для меня. При включении config.hpp я получал те же сообщения об ошибках, что и раньше. Не могли бы вы объяснить мне, в чем разница, когда включается только config.hpp? - person dimmigen; 02.08.2016
comment
@dimmigen Допустим, у вас есть несколько функций, которые используют только библиотеку arpack. Если вы поместите все это в some.c файл #include "arpack" только в some.c файл, а не в соответствующий some.h файл. По сути, это будет означать, что вы используете функции на основе заголовка только один раз. - person silvergasp; 03.08.2016

Во-первых, защита включения не помогает на данном этапе, поскольку предотвращает только многократное включение заголовка в «поддерево» графа зависимостей файлов вашего проекта. Другими словами: если вы включаете заголовок в два полностью разделенных файла одного и того же проекта, препроцессор c ++ заменит #include <header.h> дважды и независимо на код, указанный в заголовке. Это нормально, если заголовок содержит только объявления.

В вашем случае (и во многих других библиотеках только для заголовков) определения также предоставляются в заголовках. Так что, к сожалению (насколько мне известно), нет никакого элегантного способа, кроме как включить файлы, содержащие определения, один раз в ваш проект. https://github.com/m-reuter/arpackpp/blob/master/include/README явно указывает, какие файлы содержат определения.

Однако некоторые библиотеки предоставляют макросы препроцессора для включения определений для предоставленных файлов заголовков (например, https://github.com/nothings/stb). Возможно, arpackpp предоставляет аналогичные механизмы.

person Felix Lauer    schedule 29.07.2016
comment
Спасибо за ответ. Под arkcpp вы имели в виду arpackpp? Или это имя другой библиотеки cpp? Быстрое исследование Google не выявило ничего, связанного с этой темой. - person dimmigen; 02.08.2016
comment
Извините, только опечатка. Конечно я имею в виду arpackpp :). Исправлю опечатку в своем ответе. - person Felix Lauer; 03.08.2016