У меня есть простая, но смущающая проблема. Я искал вокруг и сети, и я не нашел ничего, что помогает. Я знаю, что эта проблема распространена, и подобные вопросы были заданы при переполнении стека, но они не помогли мне решить эту проблему;
Я создаю приложение, которое использует ITK и VTK в C++. Он построен с использованием cmake с unix make, я использую OS X 10.8.4 и компилирую с использованием g++ - 4.2. У меня есть структура, которая выглядит так:
src
├── VascSeg //contains ITK filters that I have written
├── lib //contains header/source for some utility functions that I commonly use
└── test //contains tests for VascSeg Library
Вот ошибка, которую я получаю:
Undefined symbols for architecture x86_64:
"void MyUt::print_vector<float>(std::vector<float, std::allocator<float> >&, char const*)", referenced from:
_main in VascularLevelSetTest.cxx.o
"void MyUt::DeepCopy<itk::Image<float, 2u> >(itk::Image<float, 2u> const*, itk::Image<float, 2u>::Pointer)", referenced from: itk::CommandLevelSetObserver<...>in VascularLevelSetTest.cxx.o
itk::CommandLevelSetObserver<...>:
:SaveWriteImage(...)in VascularLevelSetTest.cxx.o
ld: symbol(s) not found for architecture x86_64
Как правило, это ошибка с неправильным включением или неправильной ссылкой. Тем не менее, есть ряд других функций, которые я использую в этих файлах, и они отлично работают... Я также недавно изменил структуру файлов, чтобы использовать заголовок (.h) с исходной структурой (.cxx). Ранее я помещал объявление и реализацию в один файл.h. Файл слишком длинный и дезорганизованный, поэтому я реорганизован в структуру заголовка/источника.
Соответствующие линии:
using namespace MyUt;
...
std::vector<std::vector<float> > paramList_p1
std::vector<float> params1 = paramList_p1[config];
...
print_vector <float> (params1,"\t");
MyUtils.h:
namespace MyUt{
...
template<class T>
void print_vector(std::vector<T> &vec,const char* end = "\t");
...
}
MyUtils.cxx:
namespace MyUt{
...
template<class T>
void print_vector(std::vector<T> &vec,const char* end = "\t")
{...}
...
}
Библиотека /CMakeLists.txt:
add_library(MyUtils SHARED MyUtils.cxx
vtkUtils.cxx)
SET_TARGET_PROPERTIES(MyUtils PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(MyUtils ${ITK_LIBRARIES} ${VTK_LIBRARIES})
тест /CMakeLists.txt:
add_executable(VST VascularLevelSetTest.cxx)
TARGET_LINK_LIBRARIES(VST MyUtils)
TARGET_LINK_LIBRARIES(VST ${ITK_LIBRARIES})
Прошу прощения, если это повторный вопрос, но все, что я нашел, мне не помогли.
РЕДАКТИРОВАТЬ:
Я оставил строки для ошибки DeepCopy, но я решил, что проблемы, вероятно, связаны. Поэтому я оставил его, чтобы сохранить мой пост более кратким.
Ваша проблема заключается в следующем: функция шаблона (print_vector
здесь) должна быть либо явно созданной, либо ее определение (тело) должно быть доступно в каждой единицы перевода, в которой оно используется.
Как правило, это означает, что вы никогда не можете поместить определение функции шаблона в файл .cxx
(как вы это делали здесь) и ожидаете, что он будет работать.
Он может работать с одной версией компилятора, только для разрыва со следующей версией, или он может вообще не работать.
TL; DR Переместите тело print_vector
из MyUtils.cxx
в MyUtils.h
.