我目前正在编写一个VisualC 12 Tensorflow Wrapper来为Tensorflow Object Detection API启用推理任务 . 但是,我得到了LNK2019类型的一些链接错误(“未解析的外部符号”) .
我研究了这个错误的一些常见原因并发现了以下内容,但我无法在我的代码中发现任何这些(原因列在The Microsoft reference for Linker Tool Error LNK2019上) .
以下是导致错误的代码片段:
- 文件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();
};
}
- TensorflowTensor.cpp中的实现(仅导致链接器错误的行):
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);
}
}
- 以下是我调用函数的行(在方法中:
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 }}));
}
}
如果我评论这些行,我不会得到错误 .
我已经包含了所有Header文件,并且除了以下5个LNK2019之外没有任何编译器错误或警告:
TensorflowInference.obj:错误LNK2019:未解析的外部符号“public:class tf :: TensorflowTensor :: TensorView __cdecl tf :: TensorflowTensor :: View(void)”(?? $ View @ M $ 01 @ TensorflowTensor @ tf @@ QEAA? AV?$ TensorView @ M $ 01 @ 01 @XZ)在函数“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:错误LNK2019:未解决的外部问题符号“public:float const&__cdecl tf :: TensorflowTensor :: TensorView :: operator()(class std :: array)const”(?? ?? R?$ TensorView @ M $ 01 @ TensorflowTensor @ tf @@ QEBAAEBMV?$ array @ _K $ 01 @ std @@@ Z)在函数“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:e rror LNK2019:未解析的外部符号“public:unsigned __int64 __cdecl tf :: TensorflowTensor :: TensorView :: NumElements(void)const”(?NumElements @?$ TensorView @ M $ 01 @ TensorflowTensor @ tf @@ QEBA_KXZ)在函数“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:错误LNK2019:未解析的外部符号“public:class tf :: TensorflowTensor :: TensorView __cdecl tf :: TensorflowTensor ::查看(无效)“(查看@M $ 02 @ TensorflowTensor @ tf @@ QEAA?AV?$ TensorView @ M $ 02 @ 01 @ XZ)在函数”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:错误LNK2019:未解析的外部符号“public: float const& cdecl tf :: TensorflowTensor :: TensorView :: operator()(class std :: array)const“(?? R?$ TensorView @ M $ 02 @ TensorflowTensor @ tf @@ QEBAAEBMV?$ array @ _K $ 02 @std @@@ Z)在函数“public:void __cdecl tf :: TensorflowInference :: detect(class cv :: Mat const&,class std :: vector>&)const”中引用(?detect @ TensorflowInference @ tf @@ QEBAXAEBVMat @ CV @@ AEAV?$ @载体@ UDetection TF @@ V'$ @分配器@ UDetection TF @@@ STD @@@ STD @@@ Z)
主啊,那是一面文字,但我只包括错误的重要线条 .
我感谢任何帮助我解决这些错误的提示!我对C编程还很陌生,特别是模板仍然给我带来了一些痛苦 .
1 回答
C编译器包含两个主要阶段:
如果没有发生编译时错误,则构建过程将移至:
因此,记住这些信息,让我们来看看你的错误:'LNK2019' . 这意味着它是一个链接时间错误(用LNK表示),错误号表示一个未解析的符号,在几个地方,提到TensorFlowTensor,它表示您刚刚发布的文件 .
因此,正在发生的事情是链接器无法找到每个错误中指定的函数的定义 . 在这个非常具体的案例中,其原因在于您已在cpp文件中提供模板化函数的实现 .
这将导致问题,因为模板函数必须内联定义,即在头文件中定义 .
将
TensorflowTensor.cpp
中的所有代码移动到TensorflowTensor.h
,如下所示:这样,编译器和链接器可以找到您要使用的函数的定义 .