2016-07-29 2 views
0

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

/.../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 function std :: iterator_traits :: iterator_category std :: __ iterator_category (char * const &) ': /.../Files/ включает в себя /../../../ arpack ++/включать/arerror.h: 163: несколько определение ArpackError::code' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In function станд :: вектор> :: max_size() сопз ':

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

+0

Возможно, вы могли бы уточнить свои ошибки ... «множественные определения ...» могли бы означать несколько вещей? Вы можете сделать это, отредактировав свой вопрос. – silvergasp

ответ

0

В общем, самым простым способом работы с библиотеками только для заголовков является расширение кода только с использованием заголовков. Если вы используете правильные защитники заголовков, это устранит проблему с несколькими определениями вашего кода. Если у вас есть большая база существующего кода, я бы предложил вам переименовать все ваши файлы *.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 и ссылку.

+0

Спасибо за ответ. Изменение моих файлов в hpp действительно помогло. Единственный недостаток \t в том, что мой файл make не распознает никаких шансов в моих * .hpp-файлах. – dimmigen

+0

Ваше второе предложение не помогло мне. При включении config.hpp я получил те же сообщения об ошибках, что и раньше. Не могли бы вы объяснить мне, в чем разница, включая только config.hpp? – dimmigen

+0

@dimmigen Скажите, что у вас есть ряд функций, которые используют библиотеку arpack. Если вы поместите все это в файл 'some.c'' #include "arpack" 'только в файле' some.c', а не в соответствующем 'some.h' файле. Это будет означать, что вы используете только функции, основанные на заголовках. – silvergasp

0

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

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

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

+0

Спасибо за ответ. С arkcpp вы имели в виду arpackpp? Или это имя другой библиотеки cpp? В результате быстрого исследования Google не появилось ничего, связанного с этой темой. – dimmigen

+0

Извините, просто опечатка. Конечно, я имею в виду arpackpp :). Я исправлю опечатку в своем ответе. –