QT 自定义插件问题 error: LNK2001: 无法解析的外部符号

为了重复利用已有的代码,我使用自定义插件进行开发。当每个插件独立开发时没有遇到问题,但是当插件B引用了插件A时就会在编译时报错 error: LNK2001: 无法解析的外部符号。
例如,先定义一个插件ColorPicker,用于颜色选取。关键代码如下:

class QDESIGNER_WIDGET_EXPORT ColorPicker : public QWidget {     Q_OBJECT     Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)  public:     explicit ColorPicker(QWidget *parent = nullptr);     ~ColorPicker();     QColor getColor() const;     void setColor(QColor newColor); Q_SIGNALS:     void colorChanged(const QColor oldColor, const QColor newColor); protected:     void paintEvent(QPaintEvent *event);     void mousePressEvent(QMouseEvent *event); private:     QScopedPointer<ColorPickerPrivate> d_ptr;     Q_DECLARE_PRIVATE(ColorPicker) }; 

该插件在APP中使用正常,但是当在另外一个插件LineProperty中使用ColorPicker 时就会报错。

class QDESIGNER_WIDGET_EXPORT LineProperty : public QWidget {     Q_OBJECT     Q_PROPERTY(Qt::PenStyle lineStyle READ lineStyle WRITE setLineStyle NOTIFY lineStyleChanged FINAL);     Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged FINAL);     Q_PROPERTY(QColor lineColor READ lineColor WRITE setLineColor NOTIFY lineColorChanged FINAL); public:     explicit LineProperty(QWidget *parent = nullptr);     ~LineProperty();     Qt::PenStyle lineStyle() const;     void setLineStyle(Qt::PenStyle newLineStyle);     qreal lineWidth() const;     void setLineWidth(qreal newLineWidth);     QColor lineColor() const;     // 在UI中使用了ColorPicker 插件     void setLineColor(const QColor &newLineColor);  Q_SIGNALS:     void linePropertyChanged(Qt::PenStyle style, QColor Color, qreal width);     void lineStyleChanged(Qt::PenStyle style);     void lineWidthChanged(qreal width);     void lineColorChanged(QColor color); protected:     bool eventFilter(QObject *watched, QEvent *event) override; private slots:     void on_lineStyle_currentIndexChanged(int index);     void on_lineColor_colorChanged(const QColor &oldColor, const QColor &newColor);     void on_lineWidth_valueChanged(int arg1); private:     QScopedPointer<LinePropertyPrivate> d_ptr;     Q_DECLARE_PRIVATE(LineProperty)     Q_DISABLE_COPY(LineProperty) }; 

网上大部分解决方法是这样的:

如果用到信号槽但类的定义没有放在.h文件中, qmake不会自动调moc, 你就需要写#include "moc_ColorPicker.cpp"告诉qmake你有文件需要moc

经过验证,在LineProperty .cpp文件末尾追加#include "moc_ColorPicker.cpp" 确实没有再报错。
实际上是编译器在LINK这个环节没有找到ColorPicker库文件,但是在pro文件中已经配置LIBS += -L$$OUT_PWD/../ColorPicker/release/ -lcolorpickerplugin
问题只可能是ColorPicker.h文件的定义问题。
ColorPicker类定义使用了QDESIGNER_WIDGET_EXPORT 宏,该宏用于将自定义组件类从插件导出给 Qt Designer 使用。查看QDESIGNER_WIDGET_EXPORT 的定义如下:

#if defined(QDESIGNER_EXPORT_WIDGETS) #  define QDESIGNER_WIDGET_EXPORT Q_DECL_EXPORT #else #  define QDESIGNER_WIDGET_EXPORT Q_DECL_IMPORT #endif 

LineProperty 引入ColorPicker.h文件时QDESIGNER_WIDGET_EXPORT 仍然解释为Q_DECL_EXPORT,从而导致ColorPicker库文件没有被导入到LineProperty ,所以LINK时会报错。

只需要修改ColorPicker.h文件定义,使用ColorPicker 专属的COLOR_PICKER_EXPORT即可:

#if defined(COLOR_PICKER_LIB) #define COLOR_PICKER_EXPORT Q_DECL_EXPORT #else #define COLOR_PICKER_EXPORT Q_DECL_IMPORT #endif class COLOR_PICKER_EXPORT ColorPicker : public QWidget {    ...略 }; 

参考:
error LNK2001: 无法解析的外部符号 Qt的moc机制
vs+qt error LNK2001: 无法解析的外部符号 “public: static struct QMetaObject 。。

发表评论

评论已关闭。

相关文章