QT中使用QSerialPortinfo时出现问题。。代码和debug内容贴上。。。急等。。。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT中使用QSerialPortinfo时出现问题。。代码和debug内容贴上。。。急等。。。相关的知识,希望对你有一定的参考价值。
QWidget w;
w.setWindowTitle(QString("Info about all available serial ports."));
QVBoxLayout *layout = new QVBoxLayout;
foreach(const QSerialPortInfo &SerialPortInfo,QSerialPortInfo ::availablePorts())
QString s = QString("Port: ") + SerialPortInfo.portName() + "\n";
QLabel *label = new QLabel(s);
layout->addWidget(label);
w.setLayout(layout);
w.show();
编译时出现较多err
1>main.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall QSerialPortInfo::QSerialPortInfo(class QSerialPortInfo const &)" (__imp_??0QSerialPortInfo@@QAE@ABV0@@Z),该符号在函数 "private: void __thiscall QList<class QSerialPortInfo>::node_copy(struct QList<class QSerialPortInfo>::Node *,struct QList<class QSerialPortInfo>::Node *,struct QList<class QSerialPortInfo>::Node *)" (?node_copy@?$QList@VQSerialPortInfo@@@@AAEXPAUNode@1@00@Z) 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall QSerialPortInfo::~QSerialPortInfo(void)" (__imp_??1QSerialPortInfo@@QAE@XZ),该符号在函数 "public: void * __thiscall QSerialPortInfo::`scalar deleting destructor'(unsigned int)" (??_GQSerialPortInfo@@QAEPAXI@Z) 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: class QString __thiscall QSerialPortInfo::portName(void)const " (__imp_?portName@QSerialPortInfo@@QBE?AVQString@@XZ),该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: static class QList<class QSerialPortInfo> __cdecl QSerialPortInfo::availablePorts(void)" (__imp_?availablePorts@QSerialPortInfo@@SA?AV?$QList@VQSerialPortInfo@@@@XZ),该符号在函数 _main 中被引用
1>C:\Users\Rambo\Documents\Visual Studio 2012\Projects\enumCom\Win32\Debug\\enumCom.exe : fatal error LNK1120: 4 个无法解析的外部命令
========== 全部重新生成: 成功 0 个,失败 1 个,跳过 0 个 ==========
很急。。。。望大侠帮忙看下。。在线等。。。
是什么类来的,这个错误主要是你调用的那几个函数没实现。本回答被提问者采纳
在 Qt 中移动头文件时出现奇怪的预处理器行为
【中文标题】在 Qt 中移动头文件时出现奇怪的预处理器行为【英文标题】:Strange preprocessor behaviour when moc'ing a header file in Qt 【发布时间】:2016-06-02 22:59:23 【问题描述】:在尝试将 Qt 元对象编译器 (moc) 应用于 Qt 项目中的头文件时,我遇到了一个令人费解的问题。我正在使用 Visual Studio 2013,并使用自定义构建工具执行 moc 步骤,该工具最初是使用 Qt Visual Studio 插件自动生成的。
首先,一些乏味但高度相关的背景。我的项目涉及将来自相机的数据(可能是多种不同类型中的任何一种)流式传输到 GUI 中。某些类仅在我正在编译代码的特定工具上可用某些相机 SDK 时才相关;如果任何一个可能的相机 SDK 可用,则某些类是相关的,但如果 没有 SDK 可用,则应该不编译。为了处理这个问题,我有一个名为“Support.h”的通用头文件,它目前包含以下代码:
#if defined(PTGREY_SUPPORT) || defined(SVS_VISTEK_SUPPORT)
#define CAMERA_SUPPORT
#endif
#ifdef CAMERA_SUPPORT
#pragma message ("Support for at least one camera is available")
#else
#pragma message ("No support is available for any camera on this machine")
#endif
每个受影响的 .h 文件和 .cpp 文件都有结构
#include "Support.h"
#ifdef CAMERA_SUPPORT
... the whole file contents
#endif
一般来说,这是一种享受:如果我有一个合适的相机 SDK,并且我单独编译了一个 .cpp,那么一切都可以干净地编译,我会看到“支持至少一个相机可用”消息抛出所有正确的地方。
但是,如果我尝试构建整个项目,则会收到一堆链接错误,因为没有生成 Qt 信号和插槽所需的元对象函数。在进一步调查中,我发现虽然 .h 文件正在按照应有的方式进行 moc,但 moc 编译器正在输出错误消息“注意:未找到相关类。未生成输出。”每次生成 moc_[class name].cpp 文件,虽然它们都在生成,但都是空的!
返回头文件并手动将 '#include "Support.h"' 替换为 '#define CAMERA_SUPPORT' 一下子解决了问题,但完全违背了我想要实现的目标。
好像是这样的:
-
编译 .cpp 文件时,预处理器会解析“Support.h”的内容,定义 CAMERA_SUPPORT,然后正确查看和编译所有相关代码块。
但是,当一个 .h 文件被 moc'ed 时,“Support.h”被忽略并且 CAMERA_SUPPORT 保持未定义。但是,预处理器仍然会删除 '#ifdef CAMERA_SUPPORT' 和 '#endif' 之间的所有内容,因此 moc 实际看到的是一个空文件。
所以,在一行中,这是我的问题:为什么当文件被 moc'ed 时,预处理器被调用来检查 CAMERA_SUPPORT is 是否定义,而不是检查 CAMERA_SUPPORT 应该定义吗?
[注:我也试过用 Support.h 的 contents 替换 '#include "Support.h"' 行,这没什么区别。因此,moc'ing 期间的问题似乎是“#if defined(...”行没有被执行,而不是它没有包含 Support.h。]
【问题讨论】:
您的任何一条编译指示消息都会被打印出来吗? @AndyG 不,他们没有,在运行 moc 时,但请参阅下面我与 Benjamin T 的通信;看起来当 moc 正在预处理文件本身时它忽略了编译指示。 【参考方案1】:Qt moc 工具不使用(由 C++ 预处理器)预处理的 .h 文件,而是直接使用您的 .h 文件并进行自己的预处理。
确保当 moc 被执行时,它拥有关于你的 DEFINES 和包含目录的所有信息(参见 doc)。可能是缺少定义。
作为替代方案,您可以使用 Q_MOC_RUN
定义,但我不推荐它。
【讨论】:
感谢您的洞察力;我尝试了另一个实验,并在 Support.h 的第一行中添加了一个显式的“#define PTGREY_SUPPORT”,而不是依赖它从 Visual Studio 项目文件中获取定义。它按预期工作。因此,这里真正的问题不是没有进行预处理,而是 moc 没有看到与预处理器相同的全局#defines。我可以通过调整用于从 Visual Studio 项目自定义构建工具中运行 moc 的命令行来解决这个问题;我会在今天晚些时候对此进行调查。【参考方案2】:来自documentation(强调我的):
另一个限制是 moc 不扩展宏,因此您不能使用宏来声明信号/插槽或使用宏来定义 QObject 的基类。
[...] 由于 moc 不扩展#defines,带参数的类型宏在信号和槽中不起作用。这是一个非法的例子:
#ifdef ultrix
#define SIGNEDNESS(a) unsigned a
#else
#define SIGNEDNESS(a) a
#endif
class Whatever : public QObject
Q_OBJECT
signals:
void someSignal(SIGNEDNESS(int));
;
没有参数的宏可以工作。
然而,这似乎在 QT5 中略有不同,尽管我认为它无论如何都不适合你(来自this discussion):
moc 在 Qt 5 中更智能:它扩展了宏。
但建议是:不要#if(任何类型)任何 不是 #defined 在同一个源中,在正在编译的源旁边的标题中,或在命令行中作为 -D 传递。
Another good discussion from
Thiago Macieira 我认为非常具体地表明,在#if
后面隐藏任何东西不是一个好主意:
好吧,让我更清楚一点:Qt 4 中的 moc 不会扩展宏调用。
$ cat foo.cpp
#define FOO(x) x
#if FOO(1) class Foo : public QObject Q_OBJECT ;
#endif
$ moc -qt4.8 foo.cpp > /dev/null
foo.cpp:0:注意:未找到相关类。没有生成输出。
【讨论】:
【参考方案3】:好的,我想我已经想通了。
我在我的问题中提到,我使用的自定义构建工具最初是由 Qt Visual Studio 插件自动生成的。它的形式是:
"$(QT32)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_THREAD_SUPPORT -DQT_CORE_LIB "-I$(QT32)\include" "-I.\GeneratedFiles\." "-I $(QT32)\include\qtmain" "-I $(QT32)\include\QtCore"
'-D's 后面的各种预处理器宏是在最初创建文件时定义的,当时我安装了加载项。它们不包括我从那时起对全局宏列表所做的任何更改。如果我手动编辑自定义构建工具以包含我的新宏:
"$(QT32)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DPTGREY_SUPPORT -DSVS_VISTEK_SUPPORT "-I$(QT32)\include" "-I.\GeneratedFiles\." "-I $(QT32)\include\qtmain" "-I $(QT32)\include\QtCore"
...然后一切都按原样进行。
所以,我的问题实际上是 Visual Studio 问题 - 有没有办法获取项目中定义的所有预处理器(Visual Studio 统称为 %(PreprocessorDefinitions))并将它们应用到自定义构建工具中的命令行?我不希望能在这里得到答案,但我会调查一下......
【讨论】:
以上是关于QT中使用QSerialPortinfo时出现问题。。代码和debug内容贴上。。。急等。。。的主要内容,如果未能解决你的问题,请参考以下文章
使用 QAction 和 setToolTip() 时出现 Qt 本地化问题
尝试使用 QQmlListProperty 时出现 Qt 编译器错误