• 平台 linux
  • 开发工具 qt
  • 语言 c++



  最近写点小玩意,发现个错误,也是花了很多时间才搞清楚,记录一下排查过程。问题是主程序在加载插件时报错undefined symbol,如下展示。

动态库加载失败:  "Cannot load library ./plugins/libLogManager.so: (./plugins/libLogManager.so: undefined symbol: _ZTI4Base)"

  这个错误原因是用Qlibrary的方法errorString()得到的。因为是C++语言,好像符号前面总会加点什么东西用作区分,其实就是没有找到一个叫做Base的符号导致加载失败的。这个Base在程序中是一个抽象类,所有的插件类都要继承它。大致的目录结构,如下图。

QLibrary resolve解析 qlibrary加载失败_头文件

  base.h文件中就是Base抽象类,而这个文件在公共目录下。继承它的log类在log插件目录下。报错说找不到Base符号,可是我看Base_log文件中都已经引用了base.h,而且通过F2都能找到base.h,并且编译也正常(迷惑了我,以为base.h文件已经),然后我就不知道怎么办了,到后面解决思路就偏了。

//Base_log.h

#include  "base.h"
//中间内容省略
class Base_log : public Base
{
       //内容省略
};

  最终也是找到了原因,就是无意间看到.pro文件中只添加了包含目录,但是HEADERS下没加base.h头文件,虽然编译过了,但是实际运行却会错。

INCLUDEPATH += ../include \           #这个就是公共目录
               ../object_model

SOURCES += \
    LogManager.cpp \
    plugExport.cpp

HEADERS += \
      ...   #其他内容  
      ...
#    ../include/base.h \       就是因为没加这个导致的
      ...   #其他内容  
      ...

  其实以前用还没怎么注意HEADERS这个字段,就知道它是添加头文件引用的,这次在Qt上查了一下关于它的说明

Defines the header files for the project.
qmake automatically detects whether moc is required by the classes in the headers, and adds the appropriate dependencies and files to the project for generating and linking the moc files

  翻译过来就是,定义项目的头文件。qmake自动检测moc是否需要某个头文件中的类,并将适当的依赖项和文件添加到项目中,以生成和链接moc文件。看来是和中间文件有关系。然后我就试了一下,HEADERS下不增加../include/base.h,就不会生成moc_base.cppmoc_base.o文件,这样链接生成的.so文件也就有问题了,但是编译时不会报错。

  还是自己对程序编译运行这些机制理解不深刻,才导致了到问题的出现。希望这篇文章能对帮到读者,如果发现文中错误,还请指正,谢谢。