• 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 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 。。

  • 相关阅读:
    中间件 | Redis - [内存 & 过期策略]
    数栈xAI:轻量化、专业化、模块化,四大功能革新 SQL 开发体验
    您的配置中指定要合并远程的引用 ‘refs/heads/xxx‘,但是没有获取到这个引用。
    内网信息收集
    Pytorch分布式训练,其他GPU进程占用GPU0的原因
    min_max_gray
    mybatis
    腾讯觅影数智医疗影像平台获颁世界互联网领先科技成果大奖
    SpringBoot 整和 Netty 并监听多端口
    【愚公系列】2022年10月 LiteDB数据库-.Net Core中的使用
  • 原文地址:https://www.cnblogs.com/ITnoteforlsy/p/18103770