使用 QT 支持构建 OpenCV 时未解析的符号 QMetaObject

Posted

技术标签:

【中文标题】使用 QT 支持构建 OpenCV 时未解析的符号 QMetaObject【英文标题】:Unresolved symbols QMetaObject when building OpenCV with QT support 【发布时间】:2011-06-29 04:18:04 【问题描述】:

我在构建支持 QT 的 OpenCV_HighGui220d.lib 时遇到问题。 问题是关于QMetaObject的未解析符号,如:

    public: virtual struct QMetaObject const * __thiscall GuiReceiver::metaObject(void)const (?metaObject@GuiReceiver@@UBEPBUQMetaObject@@XZ)

我的环境: - Visual Studio 2010 - OpenCV 2.2 - QT SDK 版本:4.7.3

以下是我的构建步骤: 1.使用CMake打开C:\OpenCV2.2,勾选WITH_QTWITH_QT_OPENGL,生成vcxproj和sln文件。2.在cvconfig.h 中添加以下宏:

#define HAVE_QT
#define HAVE_QT_OPENGL
3。在VS2010中将window_QT.cpp添加到opencv_highgui.vcxproj文件中,并在window_QT.cpp中添加以下宏
#define QT_LARGEFILE_SUPPORT
#define QT_DLL
#define QT_GUI_LIB
#define QT_CORE_LIB
#define QT_HAVE_MMX
#define QT_HAVE_3DNOW
#define QT_HAVE_SSE
#define QT_HAVE_MMXEXT
#define QT_HAVE_SSE2
#define QT_THREAD_SUPPORT
我也试过用QT_NODLL替换QT_DLL,但是没有成功。 4.添加目录@987654338 @ 在链接器属性页面的附加库目录中。 5. 在附加依赖项中添加以下库:
qtmain.lib
qtmaind.lib
QtGui4.lib
QtGuid4.lib
QtCore4.lib
QtCored4.lib
QtOpenGL4.lib
QtOpenGLd4.lib
Qt3Support4.lib
Qt3Supportd4.lib
QtHelp4.lib
QtHelpd4.lib
QtDesigner4.lib
QtDesignerd4.lib
QAxContainer.lib
QAxContainerd.lib
phonon4.lib
phonond4.lib
QAxServer.lib
QAxServerd.lib
QtDeclarative4.lib
QtDeclaratived4.lib
QtDesignerComponents4.lib
QtDesignerComponentsd4.lib
QtMultimedia4.lib
QtMultimediad4.lib
QtNetwork4.lib
QtNetworkd4.lib
QtScript4.lib
QtScriptd4.lib
QtScriptTools4.lib
QtScriptToolsd4.lib
QtSql4.lib
QtSqld4.lib
QtSvg4.lib
QtSvgd4.lib
QtTest4.lib
QtTestd4.lib
QtUiTools.lib
QtUiToolsd.lib
QtWebKit4.lib
QtWebKitd4.lib
QtXml4.lib
QtXmld4.lib
QtXmlPatterns4.lib
QtXmlPatternsd4.lib
6. 最后链接器报错:
------ Build started: Project: ZERO_CHECK, Configuration: Debug Win32 ------
------ Build started: Project: opencv_highgui, Configuration: Debug Win32 ------
     Creating library C:/OpenCV2.2/Build_QT/lib/Debug/opencv_highgui220d.lib and object C:/OpenCV2.2/Build_QT/lib/Debug/opencv_highgui220d.exp
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall GuiReceiver::metaObject(void)const " (?metaObject@GuiReceiver@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall GuiReceiver::qt_metacast(char const *)" (?qt_metacast@GuiReceiver@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall GuiReceiver::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@GuiReceiver@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CvTrackbar::metaObject(void)const " (?metaObject@CvTrackbar@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CvTrackbar::qt_metacast(char const *)" (?qt_metacast@CvTrackbar@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CvTrackbar::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CvTrackbar@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const CvTrackbar::staticMetaObject" (?staticMetaObject@CvTrackbar@@2UQMetaObject@@B)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CvButtonbar::metaObject(void)const " (?metaObject@CvButtonbar@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CvButtonbar::qt_metacast(char const *)" (?qt_metacast@CvButtonbar@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CvButtonbar::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CvButtonbar@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const CvButtonbar::staticMetaObject" (?staticMetaObject@CvButtonbar@@2UQMetaObject@@B)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CvPushButton::metaObject(void)const " (?metaObject@CvPushButton@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CvPushButton::qt_metacast(char const *)" (?qt_metacast@CvPushButton@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CvPushButton::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CvPushButton@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CvCheckBox::metaObject(void)const " (?metaObject@CvCheckBox@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CvCheckBox::qt_metacast(char const *)" (?qt_metacast@CvCheckBox@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CvCheckBox::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CvCheckBox@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CvRadioButton::metaObject(void)const " (?metaObject@CvRadioButton@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CvRadioButton::qt_metacast(char const *)" (?qt_metacast@CvRadioButton@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CvRadioButton::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CvRadioButton@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CvWinProperties::metaObject(void)const " (?metaObject@CvWinProperties@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CvWinProperties::qt_metacast(char const *)" (?qt_metacast@CvWinProperties@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CvWinProperties::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CvWinProperties@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall CvWindow::metaObject(void)const " (?metaObject@CvWindow@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall CvWindow::qt_metacast(char const *)" (?qt_metacast@CvWindow@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall CvWindow::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CvWindow@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const CvWindow::staticMetaObject" (?staticMetaObject@CvWindow@@2UQMetaObject@@B)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall ViewPort::metaObject(void)const " (?metaObject@ViewPort@@UBEPBUQMetaObject@@XZ)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall ViewPort::qt_metacast(char const *)" (?qt_metacast@ViewPort@@UAEPAXPBD@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall ViewPort::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@ViewPort@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
window_QT.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const ViewPort::staticMetaObject" (?staticMetaObject@ViewPort@@2UQMetaObject@@B)
C:\OpenCV2.2\Build_QT\bin\Debug\opencv_highgui220d.dll : fatal error LNK1120: 31 unresolved externals
========== Build: 1 succeeded, 1 failed, 8 up-to-date, 0 skipped ==========

【问题讨论】:

【参考方案1】:

Qt MOC(元对象编译器)没有在您的 Qt 类文件上运行。

由于您是从 OpenCV 版本构建的,我假设 UI 类在类声明中已经有 Q_OBJECT 行。

要生成包含运行 MOC 所需的构建指令的 .vcproj 文件,请运行以下命令:

qmake -tp vc -r <yourProFile.pro>

如果这不起作用,请右键单击包含 Qt 类的 .h 文件之一。在 Properties->Custom Build Step->General 下,您应该会看到如下内容:

Command Line "$(QTDIR)\bin\moc.exe" -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." .\GeneratedFiles\$(ConfigurationName)\moc_$(InputName).cpp" "-fstdafx.h" "-f[YourQtFile.h]"
Description Moc'ing $(InputFileName)...
Outputs ".\GeneratedFiles\$(ConfigurationName)\moc_$(InputName).cpp"
Additional Dependencies "$(QTDIR)\bin\moc.exe";$(InputPath)

希望这会有所帮助。

【讨论】:

我尝试了命令:qmake -tp vc -r opencv_highgui.vcxproj。但是,它报告:opencv_highgui.vcxproj:5: Parse Error('&lt;Configuration&gt;Debug&lt;/Configuration&gt;')Error processing project file: opencv_highgui.vcxproj。 qmake 好像不支持 VS2010? 完成。在我尝试使用以下命令手动“moc”出 window_QT.h 与 Q_OBJECT 后,该项目已成功构建。命令:moc -I"%QTDIR%\include" -I"%QTDIR%\include\QtCore" -I"%QTDIR%\include\QtGui" -omoc_window_QT.cpp window_QT.h 手动配置 Qt 时,win32-msvc2008 是他们拥有的“最高”Visual Studio 指示符。我不知道VS2010是否有显着差异。 (我在 VS2005 上。)很高兴听到您的问题已解决。【参考方案2】:
    添加目录C:/QtSDK/Desktop/Qt/4.7.3/msvc2008/lib 在其他库目录中 链接器属性页

如果您使用 vs2010 构建,我建议您应该添加使用 vs2010 编译的库的目录...您的路径可能是指 vs2008 库。

【讨论】:

我安装了最新版的QT SDK,这个SDK目录下没有msvc2010的目录。 周围还有其他 lib 文件吗?我在 qt 库版本中使用 qt,它有另一个文件夹结构.. QMetaObject 应该在 QtCore4.lib 和 QtCored4.lib 中【参考方案3】:

这可能对某人有所帮助:

我在创建一个新的 QOBJECT 类时遇到了这个错误,在重新运行 qmake (Build->Run qmake),然后重新构建后它就消失了。

【讨论】:

【参考方案4】:

虽然很晚才回复.... 我按照以下步骤摆脱了上述错误:

1) 安装 OpenSource QT Version 或 QT for Visual Studio 版本。 2) 在 Visual Studio [http://qt.nokia.com/downloads/visual-studio-add-in] 中安装 Visual Studio QT 插件。 3) 使用 QT 创建项目,而不是作为普通的 Visual Studio 项目。创建的 QT 项目会自动成为 Visual Studio 项目。

对于现有的 QT 项目..... 1) 从 QT 菜单而不是 Visual Studio 的 File 菜单打开项目。

希望这能帮到你……我花了 2 天时间来完成这项工作。

【讨论】:

【参考方案5】:

我意识到这个问题/答案有点老了,但我遇到了这个问题,因为它是同一个问题的一个确切的问题,所以它仍然存在。我们有一个有点像九头蛇的开源项目。它同时使用了 WxWidgets 和 QT5(开源)。然而,它实际上并没有运行 moc 编译器,所以当我尝试使用一些线程类时遇到了主题错误。

如果您安装 Qt5,此步骤“可能”会为您完成,但我已经尝试过了,但没有通过链接步骤。我正在使用的源代码将所有内容都与一个可以正确运行 cmake 的批处理文件捆绑在一起——只是不包括 MOC。所以,要改造我必须做的事情如下。

我的解决方法是:

    手动创建一个名为 QtDir 的环境变量,并将其设置为开源项目附带的 SDK 或您下载的任何 Qt 库。 转到 Visual Studio 2019,右键单击 .H 文件。转到属性。你会看到这样的东西。起初对我来说并不明显的是“物品类型”可以点击。

    更改为“自定义构建步骤”。

    如果您有多个文件(很可能),请转到项目并为所有配置输入“自定义构建步骤”,或者直接从该文件编辑构建步骤。

一些不错的宏可能是新的: $(GeneratedFileExtension) 是 .g.cpp;但在实践中,项目建成时似乎是空的。所以我手动输入了 .g.cpp 。 %(身份) %(文件名) 但使用 %(FullFilePath)

@Gnawme 的回答让我成功了,但 $(InputFileName) 不适用于 VS2019。 (很可能 MS 向前移动了……)。此外,moc 编译器似乎没有采用 -f"filename.h" 它只是想要 filename.h

所以我的自定义构建步骤的最终“命令行”是:

$(QTDIR)bin\moc.exe -I".\GeneratedFiles\." -I"$(QTDIR)\include\." -I".\GeneratedFiles\$(ConfigurationName)\." -I"$(QTDIR)\include\QtCore\." -I"$(QTDIR)\include\QtGui\." -o".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).g.cpp" "%(FullPath)"

请注意,如果您在可执行文件路径周围加上引号,则会收到有关路径中无效字符的奇怪错误。

那么你想要一个描述:

Moc'ing %(FileName) to produce %(Filename).g.cpp

输出将是:

.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).g.cpp

现在……我尝试了一件棘手的事情;更改“将输出添加到项目类型”,然后从下拉列表中更改“C/C++ 编译器”。这意味着生成的文件将自动编译,而无需将它们“添加”到项目中。

.. 除非它不起作用。有点像骨头,但只需要做一次。文档实际上提到了这一点:

如果您希望构建系统对生成的输出文件进行操作 自定义构建工具,您必须手动将其添加到项目中。这 自定义构建工具将在构建过程中更新文件。

啊,好吧!不过这很容易,第一次构建时,它会因链接器错误而失败,这是您找到 .g.cpp 文件并添加它的线索。我添加了“.g”,因此很明显这是一个生成的文件;如果您尝试编辑文件,则会出现大量警告。不过,这样你就可以 .gitnore 东西等等。

自定义步骤应如下所示:

现在您甚至有了一个用于编译特定 .h 文件的菜单项,这在实践中看起来……很奇怪。 .h 文件没有被编译,它们被包含在内。除了 Qt。

【讨论】:

以上是关于使用 QT 支持构建 OpenCV 时未解析的符号 QMetaObject的主要内容,如果未能解决你的问题,请参考以下文章

将 QCharts 与 Visual Studio 2015 一起使用时未解析的外部符号

Qt Creator LNK2019:使用 OpenCV 无法解析的外部符号

使用 Qt 和 Cuda for Python 构建 OpenCV,在 build_all cmake 目标上运行到 LNK2019

使用CUDA Driver API VS2012时未解析的外部符号

在 Windows 64 中编译 32 位应用程序时未解析的外部符号

在 Windows 上编译静态 Qt 构建时未定义的引用