Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Unresolved symbol in user DLL "public: static struct QMetaObject"
Forum Updated to NodeBB v4.3 + New Features

Unresolved symbol in user DLL "public: static struct QMetaObject"

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 450 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    roderick.huang
    wrote on last edited by
    #1

    I search Qt's community and stackoverflow, found there are many related posts, but these are not same problem what I am.

    I write a user-defined widget inheite from QOpenGLWidget, and create a DLL for it using CMake : qt-open-glpoint-cloud.

    The whole error message is:

    error LNK2001: 无法解析的外部符号 "public: static struct QMetaObject const test::gl_painter::GLCloudWidget2D::staticMetaObject" (?staticMetaObject@GLCloudWidget2D@gl_painter@test@@2UQMetaObject@@B)
    

    The CMake script list bellow:

    cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
    
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    file(GLOB SRCS src/*.cc)
    file(GLOB HEADERS ${PROJECT_SOURCE_DIR}/include/gl_widget_2d/*.h)
    
    set(target_name "gl_widget_2d")
    add_library(${target_name} SHARED ${SRCS} ${HEADERS})
    target_link_libraries(${target_name} PRIVATE Qt5::Core Qt5::Widgets Qt5::OpenGL)
    target_compile_definitions(${target_name} PUBLIC -DGL_WIDGET_2D_LIB)
    
    # set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
    set(target_gl_widget_2d ${target_name} PARENT_SCOPE)
    

    The header file of the user-defined widget:

    #pragma once
    
    // #include <memory>
    //#include <vector>
    
    #include <QBrush>
    #include <QColor>
    #include <QFont>
    #include <QList>
    #include <QOpenGLWidget>
    #include <QPen>
    #include <QWidget>
    
    #include "gl_widget_2d_exp_def.h"
    
    namespace test::gl_painter {
    
    class CloudWidget2DPaintInterface;
    class CloudWidget2DPaintDash;
    class CloudWidget2DPaintRect;
    class CloudWidget2DPaintHorizontalDashLine;
    
    class GL_WIDGET_2D_API GLCloudWidget2D : public QOpenGLWidget {
      friend class CloudWidget2DPaintHorizontalDashLine;
      friend class CloudWidget2DPaintPoints;
      friend class CloudWidget2DPaintDash;
      friend class CloudWidget2DPaintRect;
    
      Q_OBJECT
    
     public:
      GLCloudWidget2D(QWidget* parent);
      ~GLCloudWidget2D() override;
      void setBackColor(QColor color);
    
      void addPaint(CloudWidget2DPaintInterface* paint);
      const QList<QColor>& colors() const;
      QList<QColor>& colors();
    
      void setRightToLeft(bool value);
      void setBottomToTop(bool value);
    
     public Q_SLOTS:
      void animate();
    
     protected:
      void paintEvent(QPaintEvent* event) override;
      void mousePressEvent(QMouseEvent* event) override;
      void mouseMoveEvent(QMouseEvent* event) override;
      void resizeEvent(QResizeEvent* event) override;
    
     Q_SIGNALS:
      void signalPaintHit(int pid, int eid, double x, double y);
      void signalSizeChanged(QSize);
    
     protected:
      QList<CloudWidget2DPaintInterface*> paints_;
      QList<QColor> colors_;
    
     protected:
      bool right_to_left_{false}, bottom_to_top_{false};
    
     protected:
      QBrush background_;
      QBrush circleBrush;
      QFont textFont;
      QPen circlePen;
      QPen textPen;
    };
    
    }  // namespace test::gl_painter
    

    The exported symbol can be found using Dependencies, and show as below:

    2024-10-27_175907.png

    We can see that other user-defined class and it's member function is exported as __cdecl, but the static struct QMetaObject ... does'nt, which is defined in Q_OBJECT.

    So how to let this symbol mark as exported ?

    Christian EhrlicherC 1 Reply Last reply
    0
    • R roderick.huang

      I search Qt's community and stackoverflow, found there are many related posts, but these are not same problem what I am.

      I write a user-defined widget inheite from QOpenGLWidget, and create a DLL for it using CMake : qt-open-glpoint-cloud.

      The whole error message is:

      error LNK2001: 无法解析的外部符号 "public: static struct QMetaObject const test::gl_painter::GLCloudWidget2D::staticMetaObject" (?staticMetaObject@GLCloudWidget2D@gl_painter@test@@2UQMetaObject@@B)
      

      The CMake script list bellow:

      cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
      
      set(CMAKE_INCLUDE_CURRENT_DIR ON)
      set(CMAKE_AUTOUIC ON)
      set(CMAKE_AUTOMOC ON)
      set(CMAKE_AUTORCC ON)
      
      file(GLOB SRCS src/*.cc)
      file(GLOB HEADERS ${PROJECT_SOURCE_DIR}/include/gl_widget_2d/*.h)
      
      set(target_name "gl_widget_2d")
      add_library(${target_name} SHARED ${SRCS} ${HEADERS})
      target_link_libraries(${target_name} PRIVATE Qt5::Core Qt5::Widgets Qt5::OpenGL)
      target_compile_definitions(${target_name} PUBLIC -DGL_WIDGET_2D_LIB)
      
      # set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
      set(target_gl_widget_2d ${target_name} PARENT_SCOPE)
      

      The header file of the user-defined widget:

      #pragma once
      
      // #include <memory>
      //#include <vector>
      
      #include <QBrush>
      #include <QColor>
      #include <QFont>
      #include <QList>
      #include <QOpenGLWidget>
      #include <QPen>
      #include <QWidget>
      
      #include "gl_widget_2d_exp_def.h"
      
      namespace test::gl_painter {
      
      class CloudWidget2DPaintInterface;
      class CloudWidget2DPaintDash;
      class CloudWidget2DPaintRect;
      class CloudWidget2DPaintHorizontalDashLine;
      
      class GL_WIDGET_2D_API GLCloudWidget2D : public QOpenGLWidget {
        friend class CloudWidget2DPaintHorizontalDashLine;
        friend class CloudWidget2DPaintPoints;
        friend class CloudWidget2DPaintDash;
        friend class CloudWidget2DPaintRect;
      
        Q_OBJECT
      
       public:
        GLCloudWidget2D(QWidget* parent);
        ~GLCloudWidget2D() override;
        void setBackColor(QColor color);
      
        void addPaint(CloudWidget2DPaintInterface* paint);
        const QList<QColor>& colors() const;
        QList<QColor>& colors();
      
        void setRightToLeft(bool value);
        void setBottomToTop(bool value);
      
       public Q_SLOTS:
        void animate();
      
       protected:
        void paintEvent(QPaintEvent* event) override;
        void mousePressEvent(QMouseEvent* event) override;
        void mouseMoveEvent(QMouseEvent* event) override;
        void resizeEvent(QResizeEvent* event) override;
      
       Q_SIGNALS:
        void signalPaintHit(int pid, int eid, double x, double y);
        void signalSizeChanged(QSize);
      
       protected:
        QList<CloudWidget2DPaintInterface*> paints_;
        QList<QColor> colors_;
      
       protected:
        bool right_to_left_{false}, bottom_to_top_{false};
      
       protected:
        QBrush background_;
        QBrush circleBrush;
        QFont textFont;
        QPen circlePen;
        QPen textPen;
      };
      
      }  // namespace test::gl_painter
      

      The exported symbol can be found using Dependencies, and show as below:

      2024-10-27_175907.png

      We can see that other user-defined class and it's member function is exported as __cdecl, but the static struct QMetaObject ... does'nt, which is defined in Q_OBJECT.

      So how to let this symbol mark as exported ?

      Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @roderick-huang said in Unresolved symbol in user DLL "public: static struct QMetaObject":

      PUBLIC DGL_WIDGET_2D_LIB

      This does not look right.

      https://doc.qt.io/qt-6/sharedlibrary.html

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      R 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        @roderick-huang said in Unresolved symbol in user DLL "public: static struct QMetaObject":

        PUBLIC DGL_WIDGET_2D_LIB

        This does not look right.

        https://doc.qt.io/qt-6/sharedlibrary.html

        R Offline
        R Offline
        roderick.huang
        wrote on last edited by
        #3

        @Christian-Ehrlicher Thanks. But it's correct.

        The following two styles are the same:

        target_compile_definitions(${target_name} PUBLIC -DGL_WIDGET_2D_LIB)
        
        target_compile_definitions(${target_name} PUBLIC GL_WIDGET_2D_LIB)
        

        The build log message of mine:

        [build] [11/15  26% :: 8.792] "D:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.41.34120\bin\Hostx64\x64\cl.exe"   /TP -DGL_WIDGET_2D_LIB -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MESSAGELOGCONTEXT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_WARN -DSPDLOG_WCHAR_TO_UTF8_SUPPORT -Dgl_widget_2d_EXPORTS -ID:\work\web\qtOpenGLPointCloud2\build\src\gl_widget_2d -ID:\work\web\qtOpenGLPointCloud2\src\gl_widget_2d -ID:\work\web\qtOpenGLPointCloud2\build\src\gl_widget_2d\gl_widget_2d_autogen\include -ID:\work\web\qtOpenGLPointCloud2\system -ID:\work\web\qtOpenGLPointCloud2\3rd\include -ID:\work\web\qtOpenGLPointCloud2\include -external:IC:\Qt\5.15.2\msvc2019_64\include -external:IC:\Qt\5.15.2\msvc2019_64\include\QtCore -external:IC:\Qt\5.15.2\msvc2019_64\.\mkspecs\win32-msvc -external:IC:\Qt\5.15.2\msvc2019_64\include\QtWidgets -external:IC:\Qt\5.15.2\msvc2019_64\include\QtGui -external:IC:\Qt\5.15.2\msvc2019_64\include\QtANGLE -external:IC:\Qt\5.15.2\msvc2019_64\include\QtOpenGL -external:W0 /DWIN32 /D_WINDOWS /W4 /GR /EHsc /O2 /Ox /Ot /Qpar /Gy /Gw /GF /MD /O2 /Ob2 /DNDEBUG -std:c++20 /utf-8 /showIncludes /Fosrc\gl_widget_2d\CMakeFiles\gl_widget_2d.dir\src\gl_cloud_widget_2d.cc.obj /Fdsrc\gl_widget_2d\CMakeFiles\gl_widget_2d.dir\ /FS -c D:\work\web\qtOpenGLPointCloud2\src\gl_widget_2d\src\gl_cloud_widget_2d.cc
        
        1 Reply Last reply
        0
        • Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Please read the documentation I gave you so you can see when this define must be there and when not. You're doing it wrong.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          R 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            Please read the documentation I gave you so you can see when this define must be there and when not. You're doing it wrong.

            R Offline
            R Offline
            roderick.huang
            wrote on last edited by
            #5

            @Christian-Ehrlicher Thanks. It's my mistake. The compile option should be defined as PRIVATE, which means the test exe should use Q_DECL_IMPORT to link the DLL's symbols -- I'm not clear about the difference between PRIVATE and PUBLIC in CMake script.

            target_compile_definitions(${target_name} PRIVATE -DGL_WIDGET_2D_LIB)
            

            But I'm not understand why no link errors for other symbols exported in the DLL, and why the symbol static struct QMetaObject const test::gl_painter::GLCloudWidget2D::staticMetaObject which not marked as __cdecl can not link ?

            Christian EhrlicherC 1 Reply Last reply
            0
            • R roderick.huang

              @Christian-Ehrlicher Thanks. It's my mistake. The compile option should be defined as PRIVATE, which means the test exe should use Q_DECL_IMPORT to link the DLL's symbols -- I'm not clear about the difference between PRIVATE and PUBLIC in CMake script.

              target_compile_definitions(${target_name} PRIVATE -DGL_WIDGET_2D_LIB)
              

              But I'm not understand why no link errors for other symbols exported in the DLL, and why the symbol static struct QMetaObject const test::gl_painter::GLCloudWidget2D::staticMetaObject which not marked as __cdecl can not link ?

              Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @roderick-huang said in Unresolved symbol in user DLL "public: static struct QMetaObject":

              I'm not clear about the difference between PRIVATE and PUBLIC in CMake script.

              See https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#target-command-scope

              But I'm not understand why no link errors for other symbols exported in the DLL,

              They would be appear later I would guess.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved