I am currently writing a VisualC++ 12 Tensorflow Wrapper to enable Inference Tasks for the Tensorflow Object Detection API. However, I get some linking errors of the Type LNK2019 ("unresolved external symbol").
I researched some usual causes for this error and found the following, but I am not able to spot any of these in my code (The causes are listed on The Microsoft reference for Linker Tool Error LNK2019).
Here are the code snippets, that cause the Error:
File TensorflowTensor.h:
namespace tf { class TensorflowTensor : public TensorflowCWrapper<TF_Tensor> { public: TensorflowTensor(const cv::Mat& input_image); TensorflowTensor(TF_Tensor* tensor); // inner class for convenient access to tensors' data template<typename DType, size_t D> class TensorView { public: TensorView<DType, D>(TensorflowTensor& tensor); const DType& operator()(std::array<size_t, D> n) const; DType& operator()(std::array<size_t, D> n); size_t NumElements() const; private: DType* data_; std::array<size_t, D> dims_; size_t num_el_; }; template<typename DType, size_t D> TensorView<DType, D> View(); }; }
The Implementation in TensorflowTensor.cpp (only the lines, that cause the linker error):
namespace tf { // Constructors of TensorflowTensor are here template<typename DType, size_t D> TensorflowTensor::TensorView<DType, D>::TensorView(TensorflowTensor& tensor) { if (tensor.NumDims() != D) { throw std::runtime_error("Number of dimensions do not match!"); } num_el_ = 1; for (size_t i = 0; i < D; ++i) { dims_[i] = tensor.Dim(i); num_el_ *= dims_[i]; } if (tensor.NumBytes() != (num_el_ * sizeof(DType))) { throw std::runtime_error("Wrong TensorView!"); } data_ = static_cast<DType*>(tensor.Bytes()); } template<typename DType, size_t D> const DType& TensorflowTensor::TensorView<DType, D>::operator()(std::array<size_t, D> n) const { return data_[ComputeOffset(n)]; } template<typename DType, size_t D> DType& TensorflowTensor::TensorView<DType, D>::operator()(std::array<size_t, D> n) { return data_[ComputeOffset(n)]; } template<typename DType, size_t D> size_t TensorflowTensor::TensorView<DType, D>::NumElements() const { return num_el_; } template<typename DType, size_t D> TensorflowTensor::TensorView<DType, D> TensorflowTensor::View() { return TensorView<DType, D>(*this); } }
And here are the lines from which i call the functions (In a method:
TensorflowInference::detect(* some args */)
):const auto output_scores = result_tensors[0]->TensorflowTensor::View<float, 2>(); const auto output_boxes = result_tensors[1]->TensorflowTensor::View<float, 3>(); const auto output_classes = result_tensors[2]->TensorflowTensor::View<float, 2>(); // copy detections to the results vector results.clear(); for (size_t i = 0; i < output_scores.NumElements(); ++i) { if (output_scores({{0, i}}) > 0.) { results.emplace_back(output_classes({{ 0, i }}), output_scores({{ 0, i }}), output_boxes({{ 0, i, 1 }}), output_boxes({{ 0, i, 0 }}), output_boxes({{ 0, i, 3 }}), output_boxes({{ 0, i, 2 }})); } }
I don't get the error if I comment these lines.
I have included all Header Files and don't get any compiler errors or warnings except for the following 5 LNK2019s:
TensorflowInference.obj : error LNK2019: unresolved external symbol "public: class tf::TensorflowTensor::TensorView __cdecl tf::TensorflowTensor::View(void)" (??$View@M$01@TensorflowTensor@tf@@QEAA?AV?$TensorView@M$01@01@XZ) referenced in function "public: void __cdecl tf::TensorflowInference::detect(class cv::Mat const &,class std::vector > &)const " (?detect@TensorflowInference@tf@@QEBAXAEBVMat@cv@@AEAV?$vector@UDetection@tf@@V?$allocator@UDetection@tf@@@std@@@std@@@Z)
TensorflowInference.obj : error LNK2019: unresolved external symbol "public: float const & __cdecl tf::TensorflowTensor::TensorView::operator()(class std::array)const " (??R?$TensorView@M$01@TensorflowTensor@tf@@QEBAAEBMV?$array@_K$01@std@@@Z) referenced in function "public: void __cdecl tf::TensorflowInference::detect(class cv::Mat const &,class std::vector > &)const " (?detect@TensorflowInference@tf@@QEBAXAEBVMat@cv@@AEAV?$vector@UDetection@tf@@V?$allocator@UDetection@tf@@@std@@@std@@@Z)
TensorflowInference.obj : error LNK2019: unresolved external symbol "public: unsigned __int64 __cdecl tf::TensorflowTensor::TensorView::NumElements(void)const " (?NumElements@?$TensorView@M$01@TensorflowTensor@tf@@QEBA_KXZ) referenced in function "public: void __cdecl tf::TensorflowInference::detect(class cv::Mat const &,class std::vector > &)const " (?detect@TensorflowInference@tf@@QEBAXAEBVMat@cv@@AEAV?$vector@UDetection@tf@@V?$allocator@UDetection@tf@@@std@@@std@@@Z)
TensorflowInference.obj : error LNK2019: unresolved external symbol "public: class tf::TensorflowTensor::TensorView __cdecl tf::TensorflowTensor::View(void)" (??$View@M$02@TensorflowTensor@tf@@QEAA?AV?$TensorView@M$02@01@XZ) referenced in function "public: void __cdecl tf::TensorflowInference::detect(class cv::Mat const &,class std::vector > &)const " (?detect@TensorflowInference@tf@@QEBAXAEBVMat@cv@@AEAV?$vector@UDetection@tf@@V?$allocator@UDetection@tf@@@std@@@std@@@Z)
TensorflowInference.obj : error LNK2019: unresolved external symbol "public: float const & __cdecl tf::TensorflowTensor::TensorView::operator()(class std::array)const " (??R?$TensorView@M$02@TensorflowTensor@tf@@QEBAAEBMV?$array@_K$02@std@@@Z) referenced in function "public: void __cdecl tf::TensorflowInference::detect(class cv::Mat const &,class std::vector > &)const " (?detect@TensorflowInference@tf@@QEBAXAEBVMat@cv@@AEAV?$vector@UDetection@tf@@V?$allocator@UDetection@tf@@@std@@@std@@@Z)
Lord, that's a wall of text, but I included only the important lines for the error.
I appreciate any hint that helps me to solve these errors! I'm still quite new to C++ programming and especially the templates are still giving me some pain in the neck.