MVC++: error LNK2019

  • Hallo!

    Bin gerade an einem Projekt, das ich mit C++ unter Microsoft Visual Studio 2008 entwickele. Ich hatte im übernommenen Kode mehrere Methoden, die zahlen einlasen. Die möchte ich als Vorlagen (templates) zusammenfassen. Die Übersetzung ist OK, aber die Bindung (link) gibt Fehlermeldungen aus.

    Meine Methodendefinition:

    Header-Deklaration:
    template <class T>
    bool ReadNumber(const LPCTSTR szName, T &nValue, const T nDefValue);

    Diese Methode soll jetzt ReadFloat, ReadBool, ReadInt usw. ersetzen. Komischer Weise hat der Binder keine Freude damit. Ich scheine etwas zu übersehen. Könnt ihr mir da weiterhelfen?

    Danke!

    Definition:
    template <class T>
    bool CPSDatFile::ReadNumber(const LPCTSTR szName, T &nValue, const T nDefValue)
    {
    bool bGotValue = false;
    stlString strBuffer;
    if(ReadString(szName, strBuffer, ""))
    {
    nValue = (T)_tstof(strBuffer.c_str());
    bGotValue = true;
    }
    else
    {
    nValue = nDefValue;
    }
    return bGotValue;
    }

    Fehlermeldungen:
    1>Algorithm.obj : error LNK2019: Verweis auf nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<float>(char const * const,float &,float)" (??$ReadNumber@M@CPSDatFile@@QAE_NQBDAAMM@Z)" in Funktion ""public: void __thiscall CAlgorithm::InitLevels(void)" (?InitLevels@CAlgorithm@@QAEXXZ)".
    1>Data.obj : error LNK2001: Nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<float>(char const * const,float &,float)" (??$ReadNumber@M@CPSDatFile@@QAE_NQBDAAMM@Z)".
    1>Algorithm.obj : error LNK2019: Verweis auf nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<int>(char const * const,int &,int)" (??$ReadNumber@H@CPSDatFile@@QAE_NQBDAAHH@Z)" in Funktion ""public: void __thiscall CAlgorithm::InitLevels(void)" (?InitLevels@CAlgorithm@@QAEXXZ)".
    1>Data.obj : error LNK2001: Nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<int>(char const * const,int &,int)" (??$ReadNumber@H@CPSDatFile@@QAE_NQBDAAHH@Z)".
    1>ScoreDisplay.obj : error LNK2001: Nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<int>(char const * const,int &,int)" (??$ReadNumber@H@CPSDatFile@@QAE_NQBDAAHH@Z)".
    1>Algorithm.obj : error LNK2019: Verweis auf nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<unsigned char>(char const * const,unsigned char &,unsigned char)" (??$ReadNumber@E@CPSDatFile@@QAE_NQBDAAEE@Z)" in Funktion ""public: void __thiscall CAlgorithm::InitLevels(void)" (?InitLevels@CAlgorithm@@QAEXXZ)".
    1>Data.obj : error LNK2001: Nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<unsigned char>(char const * const,unsigned char &,unsigned char)" (??$ReadNumber@E@CPSDatFile@@QAE_NQBDAAEE@Z)".
    1>Data.obj : error LNK2019: Verweis auf nicht aufgelstes externes Symbol ""public: static class std::vector<class Coordinates,class std::allocator<class Coordinates> > & __cdecl CAlgorithm::ReadRectangle<float>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,float &,float &,float &,float &)" (??$ReadRectangle@M@CAlgorithm@@SAAAV?$vector@VCoordinates@@V?$allocator@VCoordinates@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@AAM111@Z)" in Funktion ""public: class std::vector<class Coordinates,class std::allocator<class Coordinates> > & __thiscall CData::LevelDispVect(void)" (?LevelDispVect@CData@@QAEAAV?$vector@VCoordinates@@V?$allocator@VCoordinates@@@std@@@std@@XZ)".
    1>Data.obj : error LNK2019: Verweis auf nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<unsigned short>(char const * const,unsigned short &,unsigned short)" (??$ReadNumber@G@CPSDatFile@@QAE_NQBDAAGG@Z)" in Funktion ""private: void __thiscall CData::CreateShipModels(void)" (?CreateShipModels@CData@@AAEXXZ)".
    1>ScoreDisplay.obj : error LNK2001: Nicht aufgelstes externes Symbol ""public: bool __thiscall CPSDatFile::ReadNumber<unsigned short>(char const * const,unsigned short &,unsigned short)" (??$ReadNumber@G@CPSDatFile@@QAE_NQBDAAGG@Z)".
    1>ScoreDisplay.obj : error LNK2019: Verweis auf nicht aufgelstes externes Symbol ""public: static class std::vector<class Coordinates,class std::allocator<class Coordinates> > & __cdecl CAlgorithm::ReadRectangle<int>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,int &,int &,int &,int &)" (??$ReadRectangle@H@CAlgorithm@@SAAAV?$vector@VCoordinates@@V?$allocator@VCoordinates@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@AAH111@Z)" in Funktion ""public: int __thiscall CScoreDisplay::Setup(char const * const)" (?Setup@CScoreDisplay@@QAEHQBD@Z)".
    1>D:\Programme\CogniPlusBeta\TRAINING\VRAG\VRAGt2.exe : fatal error LNK1120: 6 nicht aufgelste externe Verweise.
    1>Das Buildprotokoll wurde unter "file://d:\Arbeit\VC2008\CogniPlus\VRAG\Win32\Debug\BuildLog.htm" gespeichert.
    1>VRAG - 12 Fehler, 1 Warnung(en)

  • Definition:


    Wo steht die Definition? Üblicherweise müssen Template-Definitionen in einem File stehen, das #includiert wird. Es gibt zwar das export-Keyword, mit dem man Template-Definitionen auch ohne #include linken können soll, aber das unterstützen nicht viele Compiler. (Ich kenn MVC++ nicht, aber es wirkt auf mich so, als würde es auch kein export können.)

    *plantsch*

  • Das ist ja gerade der Punkt: Ich habe die Vorlagenfunktion gar nicht definiert. Ich habe sie auch gar nicht deklariert! Ich habe gar keine Funktion, sondern eine Methode, die in die Klasse hineingehört. Ich programmiere sehr ungerne prozedural. Heißt das also, dass Vorlagen-Methoden praktisch unmöglich sind? Die Deklarion der Methode muss nämlich in der Klassendatei (*.H) stattfinden, die Definition auch (*.CPP), oder?

  • Ich habe die Vorlagenfunktion gar nicht definiert. Ich habe sie auch gar nicht deklariert!


    Ich weiß nicht, wovon du redest. Du hast oben eine Deklaration und eine Definition gepostet. Wenn das nicht Teile von deinem Programm sind, dann fehlt dir tatsächlich was :)

    Zitat

    Heißt das also, dass Vorlagen-Methoden praktisch unmöglich sind?


    Wenn du mit "Vorlage" "Template" meinst: Nein, Template-Methoden (member functions, wenn wir schon Wörter klauben) sind ganz und gar nicht unmöglich.

    Zitat

    Die Deklarion der Methode muss nämlich in der Klassendatei (*.H) stattfinden, die Definition auch (*.CPP), oder?


    Bei Templates muß die Definition üblicherweise eben auch im Header stehen. Oder in einer "Code"-Datei (.cpp, .c++, wie immer man sie gerne nennt), die man mit #include einbindet.

    Also wenn du in foo.h eine Klasse Foo definierst, die eine template member function hat, mußt du diese entweder auch in foo.h definieren, oder in foo_templatedefs.c++, und dieses immer #includen, wenn du die Funktion aufrufen willst, oder gleich in foo.h am Ende ein #include "foo_templatedefs.c++" einfügen.

    *plantsch*

  • Ich würde das File eher .ipp oder .i nennen, um es von normalen C++-Dateien zu unterscheiden.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!