在共享库中包含静态库会导致“未定义的引用”

问题描述

首先,让我说我在Stackoverflow上阅读了很多关于这个问题的问答,其中大部分的结论是它是一个链接排序问题。尽管如此,到目前为止我还是无法解决这个问题。

我的目标是构建一个使用外部库(OpenCV 和其他库,但现在假设它只是 OpenCV)的共享库 (libdetector.so),我想将它们嵌入到 libdetector.so 中,以便用户只需安装 libdetector.so,一切顺利。

假设 libdetector.so 的源代码detector.cc 并且看起来像这样(它还没有做任何有用的事情,但足以说明问题)

#include "detector.hh"
#include <string>
#include <vector>
#include "opencv2/opencv.hpp"
#include "opencv2/videoio.hpp"

namespace detector {

Detector::Detector(const std::string& filepath) : filepath(filepath) {}

std::vector<float> Detector::detect(float similarityThreshold) {
  cv::Mat new_img = cv::Mat::zeros(1,49,CV_64FC1);
  std::vector<float> vec{1.0,1.0,1.0};
  return vec;
}

}  // namespace detector

detector.hh 看起来像这样

#ifndef DETECTOR_H
#define DETECTOR_H

#include <string>
#include <vector>
#include "opencv2/opencv.hpp"
#include "opencv2/videoio.hpp"

namespace detector {
class Detector {
 private:
  std::string filepath;

 public:
  Detector(const std::string &filepath);
  std::vector<float> detect(float similarityThreshold = 0.7);
};
}  // namespace detector

#endif

我已经用 cmake 标志编译了 OpenCV -DBUILD_SHARED_LIBS:BOOL=OFF 并且我在 build/ 目录中有几个 OpenCV *.a 库。之后我像这样构建 libdetector.so

g++ -Wall -fPIC -shared -o libdetector.so detector.cc opencv/build/lib/*.a

这不会返回任何错误输出 libdetector.so - 到目前为止一切顺利。

下一步是一些应该使用 libdetector.so 的示例代码,我们称之为detector_use.cc

#include <iostream>
#include <string>
#include <vector>

#include "detector.hh"

int main() {
  detector::Detector d("test/path");
  std::vector<float> vec = d.detect(0.1);
  for (auto el : vec) {
    std::cout << el << std::endl;
  }
  return 0;
}

我的愿望是用户应该能够简单地编译这个

g++ -o detector_use detector_use.cc ./libdetector.so

但是这个输出

/tmp/ccseI2o0.o: In function `cv::String::~String()':
detector_use.cc:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallocate()'
/tmp/ccseI2o0.o: In function `cv::String::operator=(cv::String const&)':
detector_use.cc:(.text._ZN2cv6StringaSERKS0_[_ZN2cv6StringaSERKS0_]+0x28): undefined reference to `cv::String::deallocate()'
./libdetector.so: undefined reference to `ippicvsMaxEvery_32f'
./libdetector.so: undefined reference to `__itt_api_version_ptr__3_0'
./libdetector.so: undefined reference to `__itt_id_create_ptr__3_0'
./libdetector.so: undefined reference to `ippicvinormRel_L1_16u_C1R'
[...]

如果我理解正确,链接器会抱怨在 libdetector.so 中找不到对 ippicvsMaxEvery_32f 等的引用。为了深入研究,我跑了

me@VI:~/C-Linux$ nm -gD libdetector.so | grep ippicvsMaxEvery_32f
    U ippicvsMaxEvery_32f

这不是证明符号在那里吗?

如果我只是链接到共享的 OpenCV 库,我也像这样安装在我的机器上

g++ -g detector_use.cc detector.cc -I. -lopencv_core -lopencv_videoio -lopencv_high
gui -o detector_use

一切都按预期进行。但是,如果我跳过我的 libdetector.so 库,它为什么会失败?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)