none
Funktionen aus Headerdatei können nicht aufgeruft werden RRS feed

  • Frage

  • Hallo,

    Immer wenn ich einfach nur Leeres Projekt erstelle Passiert folgendes:

    Ich habe eine Headerdatei und habe sie auch in meinem Programm includiert.

    Da drinn ist eine Funktion die den Kreisinhalt eines Kreises berechnet.

    Ich rufe sie in meinem Programm auf und im Output Fenster sind keine Probleme.

    Aber wenn ich compiliere

    Stehen da Folgende fehler:

    "LNK1120 1 nicht aufgelöste externe       "   und,

    "LNK2019 Verweis auf nicht aufgelöstes externes Symbol ""void_cdecl Kreisinhalt (void)" in Funktion "main".     "

    Obwohl das Programm leer ist und nur die Funktion aufgerufen wird.

    Übrigens heißt die Funktion void Kreisinhalt.

    Ich habe es auch mit anderen Funktionen ausprobiert wo sogar nur was ausgegeben wird und es funktioniert trozdem nicht.

    Ich bitte um Hilfe!

    Danke


    Sonntag, 23. Juni 2019 14:28

Antworten

  • Die Art meines Projektes ist Leeres Projekt.

    Benutzung.cpp:

    #include "MeineFunktionen.h"
    
    int main (){
    Kreisinhalt();
    }

    MeineFunktionen.h

    void Kreisinhalt();


    MeineFunktionen.cpp

    #include <iostream>
    
    void Kreisinhalt (){
    std::cout << "Bitte geben sie den Radius an um die Flaeche des Kreises berechnen zu koennen: ";
    
    double Radius;
    double Pi = 3.14;
    double Flaeche = Pi *(radius * radius);
    
    std::cin >> Radius;
    std::cout << "Die Flaeche ist " << Flaeche << std::endl;
    
    }

    Du musst den Radius vor der Flaechen-Berechnung einlesen

    void Kreisinhalt (){
    double Radius;
    std::cout << "Bitte geben sie den Radius an um die Flaeche des Kreises berechnen zu koennen: ";
    std::cin >> Radius;
    
    double Pi = 3.14;
    double Flaeche = Pi *(radius * radius);
    
    std::cout << "Die Flaeche ist " << Flaeche << std::endl;
    
    }
    

    Gruß Guido

    Dienstag, 25. Juni 2019 10:58
  • du musst die cpp Datei in dein Projekt einfügen, bzw. die zugehörige Bibliothek. Die include-Datei sagt dem Compiler nur, dass es irgendwo eine Funkion gibt mit dem definierten Funktionskopf.

    Das ist falsch, die Trennung von Definition und Deklaration ist optional. Definition und Deklaration dürfen auch gemeinsam in einer Headerdatei stehen, auf diese muss nur mit

    #include

    verwiesen werden, eine cpp Datei wird dann nicht benötigt.

    Bsp.
    Header NoCpp.h:

    #pragma once
    class NoCPP
    {
    public:
    	int meinInt() { return 2; }
    };

    Verwendung:

    #include "NoCpp.h"
    
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
      NoCPP meinNoCpp;
      int nRet = meinNoCpp.meinInt();
      // nRet hat hier den Wert 2
    }

    Die Ursache für die Linker-Fehler liegt also woanders. Nach der bisherigen Beschreibung kann ich nur raten, möglicherweise ist die genannte Funktion/Methode nur Deklariert, heißt anders oder hat andere Parameter?


    - Gruß Florian


    Montag, 24. Juni 2019 07:30
  • Die Art meines Projektes ist Leeres Projekt.

    Benutzung.cpp:

    #include "MeineFunktionen.h"
    
    int main (){
    Kreisinhalt();
    }

    MeineFunktionen.h

    void Kreisinhalt();




    Ok,

    int main: du musst einen Wert zurückgeben am Ende der Funktion, z.B. return 0; Der Compiler sollte das aber auch mit einer Warnung melden.

    Wo ist MeineFunktionen.cpp? Ohne diese cpp bekommst du den LNK 2019 Fehler.

    Gruß Guido

    Dienstag, 25. Juni 2019 10:55

Alle Antworten

  • Hallo,

    du musst die cpp Datei in dein Projekt einfügen, bzw. die zugehörige Bibliothek. Die include-Datei sagt dem Compiler nur, dass es irgendwo eine Funkion gibt mit dem definierten Funktionskopf.

    https://docs.microsoft.com/de-de/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?view=vs-2019

    Gruß Guido

    Montag, 24. Juni 2019 05:49
  • du musst die cpp Datei in dein Projekt einfügen, bzw. die zugehörige Bibliothek. Die include-Datei sagt dem Compiler nur, dass es irgendwo eine Funkion gibt mit dem definierten Funktionskopf.

    Das ist falsch, die Trennung von Definition und Deklaration ist optional. Definition und Deklaration dürfen auch gemeinsam in einer Headerdatei stehen, auf diese muss nur mit

    #include

    verwiesen werden, eine cpp Datei wird dann nicht benötigt.

    Bsp.
    Header NoCpp.h:

    #pragma once
    class NoCPP
    {
    public:
    	int meinInt() { return 2; }
    };

    Verwendung:

    #include "NoCpp.h"
    
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
      NoCPP meinNoCpp;
      int nRet = meinNoCpp.meinInt();
      // nRet hat hier den Wert 2
    }

    Die Ursache für die Linker-Fehler liegt also woanders. Nach der bisherigen Beschreibung kann ich nur raten, möglicherweise ist die genannte Funktion/Methode nur Deklariert, heißt anders oder hat andere Parameter?


    - Gruß Florian


    Montag, 24. Juni 2019 07:30
  • du musst die cpp Datei in dein Projekt einfügen, bzw. die zugehörige Bibliothek. Die include-Datei sagt dem Compiler nur, dass es irgendwo eine Funkion gibt mit dem definierten Funktionskopf.

    Das ist falsch, die Trennung von Definition und Deklaration ist optional. Definition und Deklaration dürfen auch gemeinsam in einer Headerdatei stehen, auf diese muss nur mit

    #include

    verwiesen werden, eine cpp Datei wird dann nicht benötigt.

    Bsp.
    Header NoCpp.h:

    #pragma once
    class NoCPP
    {
    public:
    	int meinInt() { return 2; }
    };

    Verwendung:

    #include "NoCpp.h"
    
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
      NoCPP meinNoCpp;
      int nRet = meinNoCpp.meinInt();
      // nRet hat hier den Wert 2
    }

    Die Ursache für die Linker-Fehler liegt also woanders. Nach der bisherigen Beschreibung kann ich nur raten, möglicherweise ist die genannte Methode nur Deklariert, heißt anders oder hat andere Parameter?


    - Gruß Florian

    Na ganz so falsch war ich dann doch nicht. Wäre die Funktion in der Header definiert statt nur deklariert, gäbe es den LNK 2019 Fehler nicht.

    Wenn die Funktion "void Kreisinhalt(void)" in der Headerdatei definiert wäre, wäre die Syntax der Headerdatei falsch. Denn wenn man die Headerdatei in einer anderen Datei nochmal einbindet, ist die Funktion doppelt definiert und der Linker wird mit einer anderen Fehlermeldung meckern. Schließlich handelt es sich bei "void Kreisinhalt(void)" nicht um eine statische Funktion in einer Klasse.

    Der LNK 2019 Fehler sagt, dass die Funktion nur deklariert ist, aber nicht definiert. Insofern ist meine Annahme korrekt, dass in der include-Datei nur die Deklaration der Funktion steht. Und mit der spärlichen Beschreibung und ohne weitere Informationen über den source wird diese Annahme wohl stimmen. Es fehlt die Definition der Funktion, die entweder in einer weiteren Sourcedatei oder in einer Bibliothek zu finden ist.

    Hätte die Funktion andere Übergabeparameter oder würde anders heißen, dann würde bereits der Compiler bei der Verwendung in main meckern.

    Hier mal eine Beschreibung, was "Funktionskopf" und "Funktionsrumpf" bedeutet: https://namespace-cpp.de/std/doku.php/kennen/funktion 

    Gruß Guido

    Montag, 24. Juni 2019 09:28
  • Hallo Guido,

    Na ganz so falsch war ich dann doch nicht. Wäre die Funktion in der Header definiert statt nur deklariert, gäbe es den LNK 2019 Fehler nicht.

    Das was ich zitiert hatte, ist ganz falsch - Annahmen die da vielleicht hinter stecken, hattest Du nicht erwähnt.

    Wenn die Funktion "void Kreisinhalt(void)" in der Headerdatei definiert wäre, wäre die Syntax der Headerdatei falsch. Denn wenn man die Headerdatei in einer anderen Datei nochmal einbindet, ist die Funktion doppelt definiert und der Linker wird mit einer anderen Fehlermeldung meckern. Schließlich handelt es sich bei "void Kreisinhalt(void)" nicht um eine statische Funktion in einer Klasse.

    Das ist auch falsch, wie ich bereits schrieb und mit Beispiel zeigte, kann und darf ich meine Methoden (dasselbe gilt für Funktionen) im Header definieren. Doppelte includes sollten generell vermieden werden, mein Beispiel enthält, als zusätzlichen Guard, dafür #pragma once. Alternativ und Allgemeiner wäre das #include guard idiom - Zu Beidem, siehe auch: once

    ...

    Hätte die Funktion andere Übergabeparameter oder würde anders heißen, dann würde bereits der Compiler bei der Verwendung in main meckern.

    Der von Dir zuvor genannte Link "Linkertoolfehler LNK2019" erwähnt Unterschiede in den Parametern und der Bezeichnung explizit, inklusive Beispiel - Mag für diesen Fall nicht relevant sein, von daher mag ein Ausschluss dieser Möglichkeit korrekt sein.

    Ich könnte mir auch Vorstellen, dass der OP weder die Deklaration noch die Definition selbst geschrieben hat oder beabsichtigte eines von Beiden zu tun und in der Hoffnung, dass ein Include eines Headers (woher auch immer dieser stammen mag) schon alles mitbringt, auf diesen Linkerfehler gestoßen ist.


    - Gruß Florian

    Montag, 24. Juni 2019 11:17
  • Wenn die Funktion "void Kreisinhalt(void)" in der Headerdatei definiert wäre, wäre die Syntax der Headerdatei falsch. Denn wenn man die Headerdatei in einer anderen Datei nochmal einbindet, ist die Funktion doppelt definiert und der Linker wird mit einer anderen Fehlermeldung meckern. Schließlich handelt es sich bei "void Kreisinhalt(void)" nicht um eine statische Funktion in einer Klasse.

    Das ist auch falsch, wie ich bereits schrieb und mit Beispiel zeigte, kann und darf ich meine Methoden (dasselbe gilt für Funktionen) im Header definieren. Doppelte includes sollten generell vermieden werden, mein Beispiel enthält, als zusätzlichen Guard, dafür #pragma once. Alternativ und Allgemeiner wäre das #include guard idiom - Zu Beidem, siehe auch: once

    Für eine Memberfunktion in einer Klasse, wie du es in deinem Beispiel anbringst, hast du Recht.

    "void _cdecl Kreisinhalt(void)": Der OP redet hier also nicht von einer Memberfunktion in einer Klasse, sondern von einer globalen Funktion. Und diese Tatsache muss ich nicht einfach nur annehmen, denn für eine Memberfunktion sähe der Fehler anders aus, etwa "LNK2019... void CKlasse::Kreisinhalt(void) ...".
    Wird eine globale Funktion mehrmals in ein Projekt eingebunden (in mehreren cpp Dateien eines Projekts wird der Header included), dann hilft auch kein Compiler-pragma-once, dann wird der Linker mit dem Fehler LNK2005  (Funktion schon in einer anderen obj-Datei vorhanden) abbrechen.

    Gruß Guido

    Montag, 24. Juni 2019 12:10
  • Danke für die Anwtworten, Guido und Florian!

    Ich habe ein Ganz NEUES Projekt erstellt und alles wieder aufgeschrieben, war ja nicht viel.

    Aber wenn ich die Defenition und Deklaration getrennt abspeichere tritt auf einmal der Fehler auf : MSB6006 "CL.exe" wurde mit dem Code 2 beendet. 

    Und wenn ich deklaration und definition zusammen abspeichere, treten wieder beide Fehler auf (LNK2019... Und LNK1120)


    Montag, 24. Juni 2019 18:45
  • Danke für die Anwtworten, Guido und Florian!

    Ich habe ein Ganz NEUES Projekt erstellt und alles wieder aufgeschrieben, war ja nicht viel.

    Aber wenn ich die Defenition und Deklaration getrennt abspeichere tritt auf einmal der Fehler auf : MSB6006 "CL.exe" wurde mit dem Code 2 beendet. 

    Und wenn ich deklaration und definition zusammen abspeichere, treten wieder beide Fehler auf (LNK2019... Und LNK1120)


    Die Fehler kommen von irgendwas im Quellcode vor.

    Beschreibe, was für ein neues Projekt du erstellt hast, und zeige uns den Sourcecode der einzelnen Dateien. Sonst können wir nur raten.

    Gruß Guido

    Dienstag, 25. Juni 2019 05:54
  • Die Art meines Projektes ist Leeres Projekt.

    Benutzung.cpp:

    #include "MeineFunktionen.h"
    
    int main (){
    Kreisinhalt();
    }

    MeineFunktionen.h

    void Kreisinhalt();


    MeineFunktionen.cpp

    #include <iostream>
    
    void Kreisinhalt (){
    std::cout << "Bitte geben sie den Radius an um die Flaeche des Kreises berechnen zu koennen: ";
    
    double Radius;
    double Pi = 3.14;
    double Flaeche = Pi *(radius * radius);
    
    std::cin >> Radius;
    std::cout << "Die Flaeche ist " << Flaeche << std::endl;
    
    }

    Dienstag, 25. Juni 2019 10:48
  • Die Art meines Projektes ist Leeres Projekt.

    Benutzung.cpp:

    #include "MeineFunktionen.h"
    
    int main (){
    Kreisinhalt();
    }

    MeineFunktionen.h

    void Kreisinhalt();




    Ok,

    int main: du musst einen Wert zurückgeben am Ende der Funktion, z.B. return 0; Der Compiler sollte das aber auch mit einer Warnung melden.

    Wo ist MeineFunktionen.cpp? Ohne diese cpp bekommst du den LNK 2019 Fehler.

    Gruß Guido

    Dienstag, 25. Juni 2019 10:55
  • Die Art meines Projektes ist Leeres Projekt.

    Benutzung.cpp:

    #include "MeineFunktionen.h"
    
    int main (){
    Kreisinhalt();
    }

    MeineFunktionen.h

    void Kreisinhalt();


    MeineFunktionen.cpp

    #include <iostream>
    
    void Kreisinhalt (){
    std::cout << "Bitte geben sie den Radius an um die Flaeche des Kreises berechnen zu koennen: ";
    
    double Radius;
    double Pi = 3.14;
    double Flaeche = Pi *(radius * radius);
    
    std::cin >> Radius;
    std::cout << "Die Flaeche ist " << Flaeche << std::endl;
    
    }

    Du musst den Radius vor der Flaechen-Berechnung einlesen

    void Kreisinhalt (){
    double Radius;
    std::cout << "Bitte geben sie den Radius an um die Flaeche des Kreises berechnen zu koennen: ";
    std::cin >> Radius;
    
    double Pi = 3.14;
    double Flaeche = Pi *(radius * radius);
    
    std::cout << "Die Flaeche ist " << Flaeche << std::endl;
    
    }
    

    Gruß Guido

    Dienstag, 25. Juni 2019 10:58
  • Wenn du das return bei main einbaust, dann sollte der Compiler und Linker dort nicht mehr meckern.

    Wenn du das cin vor die Berechnung machst, kommen auch vernünftige Ergebnisse.

    Ich sehe ansonsten kein Problem deines Codes.

    Gruß Guido

    Dienstag, 25. Juni 2019 11:01