error LNK2001: unresolved external symbol “public: static struct QMetaObject 报错

最近在项目中碰到了这个报错,分析一下这个报错的产生原因以及解决办法。

首先这个错误是链接阶段的问题,也就是说链接器在通过符号查找对应的实现的时候没有找到对应的。

在网上有总结过一些可能的原因:

This can occur for four reasons:
1) the MOC compiler didn't run to create the *_moc.cpp file from the class header file,
2) MOC did run, but the generated cpp file wasn't compiled,
3) MOC did run, but the class definition was missing the Q_OBJECT macro (which defines the staticMetaObject embedded class) so the code inserted by the macro wasn't there, or
4) the object code compiled from the cpp file wasn't linked into the executable.

In the linux world, there is another possibility: the object files / libraries were not linked in the correct order. Object files must be presented to the gcc / g++ linker so any object file that is dependent on another object file (.o or .lib) must appear -before- that .o or .lib in the link command. Otherwise, dependencies discovered by the linker -after- the file that defines them has been processed will remain unresolved.

The MSVC linker is smarter; it apparently builds a table of all references contained in the object files and can resolve references anywhere they occur when processing the link command.

接下来简单介绍一个demo:

项目分为三个文件:

main.cpp
testCore.hpp
testCore.cpp

其中testCore类被封装成一个库,通过在Cmake里面添加如下代码:

#set library
set(TARGET_CORE "test-Core")
set(QUICKVTK_QT_MODULES Core Gui Widgets Quick Qml Concurrent Network DBus PrintSupport)
......
set(LINK_LIBRARIES PUBLIC ${VTK_LIBRARIES} PUBLIC Qt5::Core PUBLIC Qt5::Widgets PUBLIC Qt5::Gui PUBLIC Qt5::Quick PUBLIC Qt5::Qml PUBLIC Qt5::Concurrent)
......
add_library(${TARGET_CORE} SHARED Core/testcore.hpp Core/testcore.cpp)
set_target_properties(${TARGET_CORE} PROPERTIES PUBLIC_HEADER Core/testcore.hpp)
target_link_libraries(${TARGET_CORE} ${LINK_LIBRARIES})
......
target_link_libraries(${PROJECT_NAME}
  PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick ${TARGET_CORE})

在main.cpp中添加如下代码:

#include "Core/testcore.hpp"
......
    engine.rootContext()->findChild<testCore*>();
......

项目编译之后,产生如下报错:

main.obj:-1: error: LNK2001: 无法解析的外部符号 "public: static struct QMetaObject const testCore::staticMetaObject" (?staticMetaObject@testCore@@2UQMetaObject@@B) [D:\Projects\qtprojects\Test\build-testLinkQtLibrary-Desktop_Qt_5_15_2_MSVC2019_64bit\testLinkQtLibrary.vcxproj]

相同的代码,在ubuntu和mac平台下测试没问题,

后来想了一下原因,看了一下Qt官方文档Creating Shared Libraries | Qt 5.15

突然想起来,在windows平台库需要加上import或者export,不然的话会有问题。

于是增加一个testCore_global.hpp

里面增加如下内容:

#ifndef TESTCORE_GLOBAL_HPP
#define TESTCORE_GLOBAL_HPP

#include <QtCore/qglobal.h>

#if defined(TESTCORE_LIBRARY)
#  define TESTCORE_EXPORT Q_DECL_EXPORT
#else
#  define TESTCORE_EXPORT Q_DECL_IMPORT
#endif


#endif // TESTCORE_GLOBAL_HPP

注意这里有一个预定义的名称 “TESTCORE_LIBRARY”,这个需要在CMake文件里面启用,这里再CMake文件添加一行:

target_compile_definitions(${TARGET_CORE} PRIVATE TESTCORE_LIBRARY)

这一行的作用是,在编译阶段,为这个库增加这个变量。

也就是说,在编译库的时候,我们定义了这个TESTCORE_LIBRARY变量,这样在testCore_global.hpp中,对应的TESTCORE_EXPORT就是Q_DECL_EXPORT。

在编译主程序的时候,不会增加这个变量,所以主程序在引用testCore_global.hpp的时候,这个TESTCORE_EXPORT就是Q_DECL_IMPORT。

当然了,还有很重要的一步就是在testCore.hpp中,要修改类的声明:

class TESTCORE_EXPORT testCore
.......

这样再编译即可正常通过。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: error lnk2001: unresolved external symbol _getpriority 是一个与函数 getpriority 相关的链接错误。该错误表示在链接器阶段无法找到 getpriority 函数的定义。 getpriority 函数是用于获取进程或进程组的优先级的一个标准函数,该函数声明在头文件 #include <sys/resource.h> 中。然而,由于某些原因,链接器无法找到该函数的定义,导致出现 unresolved external symbol 错误。 要解决此问题,可以按照以下步骤操作: 1. 确保在源代码中正确地包含了 <sys/resource.h> 头文件。在 C/C++ 源文件的开头添加 #include <sys/resource.h>,以确保查找到正确的函数声明。 2. 检查编译器选项是否正确设置。有时,编译器选项可能需要手动指定以链接相应的库。对于 getpriority 函数,可能需要链接 librt 或 libpthread 库。可以尝试添加 -lrt 或 -lpthread 到编译器的选项中。 3. 确保链接器能够找到 getpriority 函数的实现。实现该函数的库文件应该与编译器链接,以便在链接器阶段解决外部符号引用。这通常涉及到正确设置库文件的路径或将库文件添加到链接器的库路径中。 总结:error lnk2001: unresolved external symbol _getpriority 是一个链接错误,表示编译器无法找到 getpriority 函数的定义。要解决此问题,需要确保正确包含头文件、正确设置编译器选项和链接库文件。 ### 回答2: error lnk2001: unresolved external symbol _getpriority是一个链接错误,意味着链接器无法解析对_getpriority的外部符号引用。 _getpriority是一个用于获取进程优先级的函数,它在Windows下没有定义,因此链接器无法找到它的定义。 要解决这个问题,可以采取以下几种方法: 1. 检查代码中是否有对_getpriority函数的调用:首先检查代码中是否存在对_getpriority函数的调用,如果没有必要使用该函数,可以删除相关的代码,这样可以避免链接错误。 2. 更改代码以使用Windows下的类似功能:如果确实需要使用进程优先级相关的功能,可以改用Windows下的类似函数来代替_getpriority。可以使用Windows API中的GetPriorityClass函数来获取进程优先级,该函数返回一个整数值表示进程的优先级类别。 3. 添加相应的库文件:如果你确定代码中需要使用_getpriority函数,可以找到包含该函数定义的库文件,并将其添加到链接器的库文件路径中。可以通过在项目属性中添加相应的附加库路径和库文件名称来实现。 总之,要解决error lnk2001: unresolved external symbol _getpriority链接错误,可以通过删除对_getpriority函数的调用、使用Windows API中的相关函数或添加相应的库文件来解决问题。 ### 回答3: 这个错误是由于在C++代码中使用了一个未解析外部符号"getpriority"所引起的。"getpriority"是一个用于获取进程优先级的函数,属于POSIX标准库中的一部分。 在C++中,要使用"getpriority"函数,需要包含对应的头文件<sys/resource.h>,并且需要链接实现该函数的库文件。根据错误提示"error lnk2001: unresolved external symbol _getpriority",可以推断出缺少对应的库文件的链接。 解决这个问题可以按照以下步骤进行: 1. 确保正确地包含了头文件<sys/resource.h>: #include <sys/resource.h> 2. 确认编译器的选项是否正确地链接了对应的库文件。 对于使用GCC编译器的情况,需要添加"-l"参数指定链接的库文件名,例如: g++ main.cpp -o main -l库文件名 3. 如果是在Windows平台上开发,可能需要使用Cygwin或MinGW等工具链来编译和链接,以确保POSIX相关的功能可用。 此外,请注意确保包含正确的库文件,并将其放置在正确的位置,以便编译器能够找到并链接到正确的实现。 总之,"error lnk2001: unresolved external symbol _getpriority"错误是由于未能解析所需库文件中的"getpriority"函数引起的。通过检查头文件和链接选项,以及在合适的位置放置正确的库文件,可以解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值