架构的重复符号x86_64 qt

时间:2017-01-17 19:08:44

标签: c++ xml qt

我从Qt开始,现在我遇到了这个错误:

Lwt

main.cpp中:

duplicate symbol _t in:
    main.o
    handler.o
duplicate symbol _mp in:
    main.o
    handler.o
duplicate symbol _l in:
    main.o
    handler.o 
duplicate symbol _ti in:
    main.o
    handler.o 
ld: 4 
duplicate symbols for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

handler.cpp:

#include "handler.h"

int main(int argc, char **argv)
{
    QFile *file = new QFile(":/xml/example.tmx");

    QXmlSimpleReader xmlReader;
    QXmlInputSource *source = new QXmlInputSource(file);

    Handler *handler = new Handler;
    xmlReader.setContentHandler(handler);
    xmlReader.setErrorHandler(handler);

    bool ok = xmlReader.parse(source);
    if (!ok)
        std::cout << "Parsing failed." << std::endl;
    else {
        QStringList names = handler->names();
        QStringList attributes = handler->attributes();
        QStringList attributeName = handler->attributeName();
        QList<int> indentations = handler->indentations();
        QList<int> anzahl = handler->anzahl();
        int items = names.count();

        int durchgang = 0;
        for (int i = 0; i < items; ++i) {
            for (int j = 0; j < indentations[i]; ++j){
                std::cout << " ";
            }
            std::cout << names[i].toLocal8Bit().constData() << " " ;
            //weitere attribute printen(so viele wie vorhanden

            for(int y = 0; y < anzahl[i] ; y++){
                std::cout << attributeName[durchgang].toLocal8Bit().constData() << " = "<< attributes[durchgang].toLocal8Bit().constData() << "   ";
                durchgang++;
            }
            std::cout << std::endl;
        }

        imageloader il;
        QStringList sources;
        for(int x = 0; x < mp.tilesets.length();x++){
            sources.append(mp.tilesets[x].source);
        }
        QList <QImage> images;
       images = il.Loadtilesets(mp.tilesets.length(),sources);
    }
    std::cout << "Beendet"<<std::endl;
    return 0;
}

handler.h中:

#include "handler.h"

/*!
    Reset the state of the handler to ensure that new documents are
    read correctly.

    We return true to indicate that parsing should continue.
*/

bool Handler::startDocument()
{
    elementName.clear();
    elementAttributes.clear();
    elementIndentation.clear();
    elementAnzahl.clear();
    elementAttributeName.clear();
    indentationLevel = 0;

    return true;
}

/*!
    Process each starting element in the XML document.

    Append the element name to the list of elements found; add its
    corresponding indentation level to the list of indentation levels.

    Increase the level of indentation by one column.

    We return true to indicate that parsing should continue.
*/

bool Handler::startElement(const QString &, const QString &,
    const QString & qName, const QXmlAttributes & atts)
{
    elementName.append(qName);
    int anzahl = 0;

    for(int index = 0; index < atts.length();index++){
        int d = index;
        if(qName == "map"){//alle attribute von map
            if(atts.qName(index) == "width"){
                mp.width = atts.value(index).toInt();
                index ++;
            }
            if(atts.qName(index)== "height"){
                mp.height = atts.value(index).toInt();
                index++;
            }
        }

        if(qName == "tileset"){
        tileset t;

            if(atts.qName(index)=="firstgid"){
                t.firstgid = atts.value(index).toInt();
                index++;
            }
            if(atts.qName(index)=="name"){
                t.name = atts.value(index);
                index ++;
            }
            if(atts.qName(index)=="tilewidth"){
                t.tilewidth = atts.value(index).toInt();
                index++;
            }
            if(atts.qName(index)=="tileheight"){
                t.tileheight = atts.value(index).toInt();
                index++;
            }
            if(atts.qName(index)=="tilecount"){
                t.tilecount = atts.value(index).toInt();
                index++;
            }
            if(atts.qName(index)=="columns"){
                t.columns = atts.value(index).toInt();
                index++;
            }
        }
        if(qName == "image"){//!muss noch ein try catch block einbauen fals ein image nicht hinter einem tileset ist
            if(atts.qName(index) == "source"){
                t.source = atts.qName(index);
                mp.tilesets.append(t);
            }
        }
        if(qName =="layer"){
            if(atts.qName(index)=="name"){
                l.name = atts.qName(index);
                index++;
            }
            if(atts.qName(index)=="width"){
                l.width = atts.qName(index).toInt();
                index++;
            }
            if(atts.qName(index)=="height"){
                l.height= atts.qName(index).toInt();
                index++;
            }
        }
        if(qName == "data"){
            for(int x = 0; x< l.height*l.width; x++){
                if(atts.qName(index)=="gid"){
                    ti.gid = atts.value(index).toInt();
                    l.tiles.append(ti);
                    index++;
                }

            }
            mp.layers.append(l);
        }

        index = d;//für das auslesen und couten
        elementAttributes.append(atts.value(index));
        elementAttributeName.append(atts.qName(index));
        anzahl = index+1;
    }

    elementAnzahl.append(anzahl);

    elementIndentation.append(indentationLevel);
    indentationLevel += 1;

    return true;
}
/*!
    Process each ending element in the XML document.

    Decrease the level of indentation by one column.

    We return true to indicate that parsing should continue.
*/

bool Handler::endElement(const QString &, const QString &,
    const QString &)
{
    indentationLevel -= 1;
    return true;
}

/*!
    Report a fatal parsing error, and return false to indicate to the reader
    that parsing should stop.
*/

bool Handler::fatalError (const QXmlParseException & exception)
{
    qWarning() << QString("Fatal error on line %1, column %2: %3").arg(
        exception.lineNumber()).arg(exception.columnNumber()).arg(
        exception.message());

    return false;
}

/*!
    Return the list of element names found.
*/

QStringList& Handler::names ()
{
    return elementName;
}

QList<int>& Handler::indentations ()
{
    return elementIndentation;
}
QStringList& Handler::attributes ()
{
    return elementAttributes;
}
QList<int>& Handler::anzahl (){
    return elementAnzahl;
}
QStringList& Handler::attributeName (){
    return elementAttributeName;
}

1 个答案:

答案 0 :(得分:0)

你似乎在.h文件中有全局变量定义,如果.h文件包含在许多.cpp文件中,这将无效(这基本上是.h文件的目的,所以...)。

要正确地执行此操作,您应该在.h文件中包含类似声明的内容:

extern int t;

然后在一个 .cpp文件中,在顶层(不在函数内),你应该有实际的定义

int t;

第一行告诉编译器某处有int t个全局变量,所以它只是使用它并信任链接器来找到它。然后,当链接器查找该符号时,它必须找到其中一个符号,否则它会抱怨重复的符号,或者没有找到符号。

我不会更深入地了解这个(hows或者为什么),但这是C ++ Qt,所以你基本上应该完全避免像这样的全局变量(它们已经足够糟糕了) C,但你有更少的选择)。既然你正在学习,你不需要强调它,现在只需使用它们,但请记住,你应该学会做事的方法,这样你就不需要它们了。