链接到 SHARED Q_OBJECT:未解析的外部符号“public:static struct QMetaObject const A::staticMetaObject”

Kas*_*zen 4 c++ windows qt cmake

我正在尝试在 Windows 上使用 cmake 制作两个 QObject 库,其中一个库依赖于另一个库。如果我将它们都构建为静态库,它就可以工作,但现在我需要将它们构建为共享库,我不断收到编译错误。

  • 错误 LNK2001:无法解析的外部符号“public:static struct QMetaObject const A::staticMetaObject”

我正在使用 Visual Studio 19 进行编译。

有问题的代码的一个小例子:

第一图书馆:

#include <QObject>
class A: public QObject
{
    Q_OBJECT
public:
    A(const QString& name){}
public Q_SLOTS:
    void ASlot(){}
};
Run Code Online (Sandbox Code Playgroud)

第二图书馆

#include "A.hpp"
class B: public A {
    Q_OBJECT
public:
    B():A("A"){}
private Q_SLOTS:
    void BSlot(){}
};
Run Code Online (Sandbox Code Playgroud)

CMakeLists.txt:

project(test)
cmake_minimum_required(VERSION 3.10)

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Modules")

find_package(Qt5Core REQUIRED)
set(CMAKE_AUTOMOC ON)

add_library(A SHARED A.hpp)
target_link_libraries(A ${Qt5Core_LIBRARIES})
set_target_properties(A PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)

add_library(B SHARED B.hpp)
target_link_libraries(B A ${Qt5Core_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

该代码已被验证可以在 Linux 上运行,所以我猜测这可能是 dll 符号导出方式的问题。我尝试使用 qt5_wrap_cpp() 而不是 automoc,但结果没有不同。

我希望有人能帮助我解决这个问题。

Ale*_*oni 7

不知道它是否仍然相关,但我通过遵循官方 Qt 创建共享库指南解决了这个问题。

在您的情况下,您应该在声明 A 类之前添加以下行:

#if defined(A_EXPORT_SYMBOLS)
#  define A_DLL_EXPORT Q_DECL_EXPORT
#else
#  define A_DLL_EXPORT Q_DECL_IMPORT
#endif
Run Code Online (Sandbox Code Playgroud)

A然后通过以下方式声明该类:

class A_DLL_EXPORT A: public QObject
{
    Q_OBJECT
public:
    A(const QString& name){}
public Q_SLOTS:
    void ASlot(){}
};
Run Code Online (Sandbox Code Playgroud)

然后,将编译定义添加到Acmake 配置中的目标中:

add_compile_definitions(A PRIVATE A_EXPORT_SYMBOLS)
Run Code Online (Sandbox Code Playgroud)

请注意,定义必须是 PRIVATE 才能Q_DECL_EXPORT仅在 A dll 中进行声明。

B类也是如此。