使用QT Creator在QSerialPort中多次定义错误

时间:2014-03-04 22:03:07

标签: c++ qt serial-port

我最近开始研究我的最终项目以完成我的学习。在这个项目中,我必须继续前任学生的工作,这需要我使用QT Creator,对我来说不为人知。 到目前为止,该项目是一个UI应用程序,用于通过串行通信从Arducopter接收数据。

当我尝试编译代码时,弹出以下错误:

C:\Qt\Qt5.1.1\5.1.1\mingw48_32\lib\libQt5SerialPortd.a(d000044.o):-1: error: multiple definition of `QSerialPort::error(QSerialPort::SerialPortError)'
debug\moc_qserialport.o:D:\Development\Code\QTWorkspace\build-BEP-Desktop_Qt_5_1_1_MinGW_32bit-Debug\debug\moc_qserialport.cpp:520: error: first defined here
C:\Qt\Qt5.1.1\5.1.1\mingw48_32\lib\libQt5SerialPortd.a(d000012.o):-1: error: multiple definition of `QSerialPort::qt_metacast(char const*)'
debug\moc_qserialport.o:D:\Development\Code\QTWorkspace\build-BEP-Desktop_Qt_5_1_1_MinGW_32bit-Debug\debug\moc_qserialport.cpp:387: error: first defined here
C:\Qt\Qt5.1.1\5.1.1\mingw48_32\lib\libQt5SerialPortd.a(d000011.o):-1: error: multiple definition of `QSerialPort::qt_metacall(QMetaObject::Call, int, void**)'
debug\moc_qserialport.o:D:\Development\Code\QTWorkspace\build-BEP-Desktop_Qt_5_1_1_MinGW_32bit-Debug\debug\moc_qserialport.cpp:395: error: first defined here
collect2.exe:-1: error: error: ld returned 1 exit status

项目只包含以下头文件,而不是相应的.cpp文件:

qserialport.h
qserialportglobal.h
qserialportinfo.h

这些是文件; qserialportglobal.h:

#ifndef QSERIALPORTGLOBAL_H
#define QSERIALPORTGLOBAL_H

#include <QtCore/qglobal.h>

QT_BEGIN_NAMESPACE

#ifndef QT_STATIC
#  if defined(QT_BUILD_SERIALPORT_LIB)
#    define Q_SERIALPORT_EXPORT Q_DECL_EXPORT
#  else
#    define Q_SERIALPORT_EXPORT Q_DECL_IMPORT
#  endif
#else
#  define Q_SERIALPORT_EXPORT
#endif

// The macro has been available only since Qt 5.0
#ifndef Q_DECL_OVERRIDE
#define Q_DECL_OVERRIDE
#endif

QT_END_NAMESPACE

#endif // QSERIALPORTGLOBAL_H

qserialportinfo.h:

    #ifndef QSERIALPORTINFO_H
#define QSERIALPORTINFO_H

#include <QtCore/qlist.h>
#include <QtCore/qscopedpointer.h>

#include <QtSerialPort/qserialportglobal.h>

QT_BEGIN_NAMESPACE

class QSerialPort;
class QSerialPortInfoPrivate;
class QSerialPortInfoPrivateDeleter;

class Q_SERIALPORT_EXPORT QSerialPortInfo
{
    Q_DECLARE_PRIVATE(QSerialPortInfo)
public:
    QSerialPortInfo();
    explicit QSerialPortInfo(const QSerialPort &port);
    explicit QSerialPortInfo(const QString &name);
    QSerialPortInfo(const QSerialPortInfo &other);
    ~QSerialPortInfo();

    QSerialPortInfo& operator=(const QSerialPortInfo &other);
    void swap(QSerialPortInfo &other);

    QString portName() const;
    QString systemLocation() const;
    QString description() const;
    QString manufacturer() const;

    quint16 vendorIdentifier() const;
    quint16 productIdentifier() const;

    bool hasVendorIdentifier() const;
    bool hasProductIdentifier() const;

    bool isNull() const;
    bool isBusy() const;
    bool isValid() const;

    static QList<qint32> standardBaudRates();
    static QList<QSerialPortInfo> availablePorts();

private:
    QScopedPointer<QSerialPortInfoPrivate, QSerialPortInfoPrivateDeleter> d_ptr;
};

inline bool QSerialPortInfo::isNull() const
{ return !d_ptr; }

QT_END_NAMESPACE

#endif // QSERIALPORTINFO_H

和qserialport.h:

    #ifndef QSERIALPORT_H
#define QSERIALPORT_H

#include <QtCore/qiodevice.h>

#include <QtSerialPort/qserialportglobal.h>

QT_BEGIN_NAMESPACE

class QSerialPortInfo;
class QSerialPortPrivate;

class Q_SERIALPORT_EXPORT QSerialPort : public QIODevice
{
    Q_OBJECT

    Q_PROPERTY(qint32 baudRate READ baudRate WRITE setBaudRate NOTIFY baudRateChanged)
    Q_PROPERTY(DataBits dataBits READ dataBits WRITE setDataBits NOTIFY dataBitsChanged)
    Q_PROPERTY(Parity parity READ parity WRITE setParity NOTIFY parityChanged)
    Q_PROPERTY(StopBits stopBits READ stopBits WRITE setStopBits NOTIFY stopBitsChanged)
    Q_PROPERTY(FlowControl flowControl READ flowControl WRITE setFlowControl NOTIFY flowControlChanged)
    Q_PROPERTY(DataErrorPolicy dataErrorPolicy READ dataErrorPolicy WRITE setDataErrorPolicy NOTIFY dataErrorPolicyChanged)
    Q_PROPERTY(bool dataTerminalReady READ isDataTerminalReady WRITE setDataTerminalReady NOTIFY dataTerminalReadyChanged)
    Q_PROPERTY(bool requestToSend READ isRequestToSend WRITE setRequestToSend NOTIFY requestToSendChanged)
    Q_PROPERTY(SerialPortError error READ error RESET clearError NOTIFY error)
    Q_PROPERTY(bool settingsRestoredOnClose READ settingsRestoredOnClose WRITE setSettingsRestoredOnClose NOTIFY settingsRestoredOnCloseChanged)

    Q_ENUMS( Directions Rate DataBits Parity StopBits FlowControl PinoutSignals DataErrorPolicy SerialPortError )

public:

    enum Direction  {
        Input = 1,
        Output = 2,
        AllDirections = Input | Output
    };
    Q_DECLARE_FLAGS(Directions, Direction)

    enum BaudRate {
        Baud1200 = 1200,
        Baud2400 = 2400,
        Baud4800 = 4800,
        Baud9600 = 9600,
        Baud19200 = 19200,
        Baud38400 = 38400,
        Baud57600 = 57600,
        Baud115200 = 115200,
        UnknownBaud = -1
    };

    enum DataBits {
        Data5 = 5,
        Data6 = 6,
        Data7 = 7,
        Data8 = 8,
        UnknownDataBits = -1
    };

    enum Parity {
        NoParity = 0,
        EvenParity = 2,
        OddParity = 3,
        SpaceParity = 4,
        MarkParity = 5,
        UnknownParity = -1
    };

    enum StopBits {
        OneStop = 1,
        OneAndHalfStop = 3,
        TwoStop = 2,
        UnknownStopBits = -1
    };

    enum FlowControl {
        NoFlowControl,
        HardwareControl,
        SoftwareControl,
        UnknownFlowControl = -1
    };

    enum PinoutSignal {
        NoSignal = 0x00,
        TransmittedDataSignal = 0x01,
        ReceivedDataSignal = 0x02,
        DataTerminalReadySignal = 0x04,
        DataCarrierDetectSignal = 0x08,
        DataSetReadySignal = 0x10,
        RingIndicatorSignal = 0x20,
        RequestToSendSignal = 0x40,
        ClearToSendSignal = 0x80,
        SecondaryTransmittedDataSignal = 0x100,
        SecondaryReceivedDataSignal = 0x200
    };
    Q_DECLARE_FLAGS(PinoutSignals, PinoutSignal)

    enum DataErrorPolicy {
        SkipPolicy,
        PassZeroPolicy,
        IgnorePolicy,
        StopReceivingPolicy,
        UnknownPolicy = -1
    };

    enum SerialPortError {
        NoError,
        DeviceNotFoundError,
        PermissionError,
        OpenError,
        ParityError,
        FramingError,
        BreakConditionError,
        WriteError,
        ReadError,
        ResourceError,
        UnsupportedOperationError,
        UnknownError
    };

    explicit QSerialPort(QObject *parent = 0);
    explicit QSerialPort(const QString &name, QObject *parent = 0);
    explicit QSerialPort(const QSerialPortInfo &info, QObject *parent = 0);
    virtual ~QSerialPort();

    void setPortName(const QString &name);
    QString portName() const;

    void setPort(const QSerialPortInfo &info);

    bool open(OpenMode mode) Q_DECL_OVERRIDE;
    void close() Q_DECL_OVERRIDE;

    void setSettingsRestoredOnClose(bool restore);
    bool settingsRestoredOnClose() const;

    bool setBaudRate(qint32 baudRate, Directions dir = AllDirections);
    qint32 baudRate(Directions dir = AllDirections) const;

    bool setDataBits(DataBits dataBits);
    DataBits dataBits() const;

    bool setParity(Parity parity);
    Parity parity() const;

    bool setStopBits(StopBits stopBits);
    StopBits stopBits() const;

    bool setFlowControl(FlowControl flow);
    FlowControl flowControl() const;

    bool setDataTerminalReady(bool set);
    bool isDataTerminalReady();

    bool setRequestToSend(bool set);
    bool isRequestToSend();

    PinoutSignals pinoutSignals();

    bool flush();
    bool clear(Directions dir = AllDirections);
    bool atEnd() const Q_DECL_OVERRIDE;

    bool setDataErrorPolicy(DataErrorPolicy policy = IgnorePolicy);
    DataErrorPolicy dataErrorPolicy() const;

    SerialPortError error() const;
    void clearError();

    qint64 readBufferSize() const;
    void setReadBufferSize(qint64 size);

    bool isSequential() const Q_DECL_OVERRIDE;

    qint64 bytesAvailable() const Q_DECL_OVERRIDE;
    qint64 bytesToWrite() const Q_DECL_OVERRIDE;
    bool canReadLine() const Q_DECL_OVERRIDE;

    bool waitForReadyRead(int msecs) Q_DECL_OVERRIDE;
    bool waitForBytesWritten(int msecs) Q_DECL_OVERRIDE;

    bool sendBreak(int duration = 0);
    bool setBreakEnabled(bool set = true);

Q_SIGNALS:
    void baudRateChanged(qint32 baudRate, QSerialPort::Directions dir);
    void dataBitsChanged(QSerialPort::DataBits dataBits);
    void parityChanged(QSerialPort::Parity parity);
    void stopBitsChanged(QSerialPort::StopBits stopBits);
    void flowControlChanged(QSerialPort::FlowControl flow);
    void dataErrorPolicyChanged(QSerialPort::DataErrorPolicy policy);
    void dataTerminalReadyChanged(bool set);
    void requestToSendChanged(bool set);
    void error(QSerialPort::SerialPortError serialPortError);
    void settingsRestoredOnCloseChanged(bool restore);

protected:
    qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE;
    qint64 readLineData(char *data, qint64 maxSize) Q_DECL_OVERRIDE;
    qint64 writeData(const char *data, qint64 maxSize) Q_DECL_OVERRIDE;

private:
    void setError(QSerialPort::SerialPortError error, const QString &errorString = QString());

    QSerialPortPrivate * const d_ptr;

    Q_DECLARE_PRIVATE(QSerialPort)
    Q_DISABLE_COPY(QSerialPort)
};

Q_DECLARE_OPERATORS_FOR_FLAGS(QSerialPort::Directions)
Q_DECLARE_OPERATORS_FOR_FLAGS(QSerialPort::PinoutSignals)

QT_END_NAMESPACE

#endif // QSERIALPORT_H

如描述中所示,错误似乎发生在moc_文件中,我不熟悉这些文件,但经过一些研究后我发现这些文件是信号函数的扩展和扩展? 错误的另一面是在标准库中找到的,我在这些文件中没有改变任何内容。

非常感谢帮助,我已经被困了几天了。

1 个答案:

答案 0 :(得分:0)

这些标题是官方Qt库的一部分,不应放在项目中。从项目中删除这些标题,然后直接从Qt中包含它们:

#include <QSerialPort>
#include <QSerialPortInfo>

moc 如何工作的解释:它扫描项目标题中的特殊QObject,并生成C ++代码(moc _ * .cpp)以使信号+插槽工作。但是,QSerialPort的生成代码已经存在于Qt库中。如果 moc 在项目中找到这些标题,它将再次生成代码,因此您可以获得QSerialPort函数的多个定义。