Visual Studio 2012 include-Dateien



  • Wenn ich in meinem Projekt ein Includeverzeichniss hinzufüge wohin ich meine .h- und .cpp-Datei kopiere kann ich die .h-Datei zwar in meinem Quellcode inkludieren, der Compiler findet aber nicht die dazugehörige .cpp-Datei.

    Beide haben den gleichen Namen, also z.B. Test.h und Test.cpp.
    Was mache ich falsch?

    Folgende Fehlermeldung kriege ich:

    Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall network::Socket::Socket(void)" (??0Socket@network@@QAE@XZ)" in Funktion "_main".
    


  • Du musst noch die cpp-Datei Deinem Projekt hinzufügen!



  • Hallo,

    ich hänge mich mal hier dran.
    Habe das gleiche Problem. Wie füge ich denn die cpp-Dateien hinzu?
    Stehe da im Moment leider etwas auf dem Schlauch und hoffe auf eure Hilfe 🙂

    Gruß
    Julian



  • cpp dateien sind die dateien, die eigentlich den binaercode erzeugen.
    also:
    cpp ->[compiler] -> obj(mehrere) -> [linker] -> .lib / .exe / .dll

    Das heisst alle cpp dateien müssen im project referenziert sein, damit sie auch den code erzeugen.

    Dateien zum project hinzufuegen geht beim VS z.b. ueber den Projectmappen-Explorer. Das Ziel-Project (ne projektmappe kann mehrere projekte haben) mit rechter maustaste, Element hinzufügen, und dann kann man im filesystem ne cpp datei auswaehlen.

    "Normal" also zumindest am Anfang bei einfacheren Projecten laesst man die sich aber eher mitm Klassengenerator hinzufügen. Also Project, neue Klasse .... der erzeugt dann ne .h und .cpp mit dem klassennamen und bindet die auch gleich ins projekt ein.

    Ciao ....



  • Danke für deine Antwort.

    Soweit hab ich das verstanden.
    Ich will aber den Code auf mehere Projekte aufteilen. Wie kann ich dann von Projekt A auf die Klassen in Projekt B zugreifen?

    Mit einem Include-Pfad kann ich immerhin schon die Header-Dateien inkludieren. Aber dann kommt beim kompilieren der Fehler "Verweis auf nicht aufgelöstes externes Symbol".
    Wenn ich die cpp-Datei ebenfalls mit include einbinde, dann geht es, aber das ist ja wohl eher nicht so sauber 🙂



  • Wenn Du auf Implementationen ausserhalb deines Projects zugreifst, muss das andere Project eine Bibliothek sein.

    einfachster Fall:

    Project A ist ne Exe (oder dll)
    Project B ist ne statische library (.lib)

    Dann kannst du von A aus ne klasse aus B verwenden,

    Header einbinden, das geeht ja schon bei dir. damit hasst die Struktur/Signatur/Definition der Klasse in A
    Um die Impl in dein Project einzufügen, musst nun noch den Binaercode von B an dein A kleben, sozusagen linken. Dazu musst du B vorher erzeugen falls sie im sourcecode vorliegt. Liegt sie als lib vor, dann bete das es nen binaercompatible Version zu deiner Visual Studio version ist 😃

    Dazu musst in deiner Projectmappe nur die Projectabhaengigkeit auf A ist abhaengig von B setzen. Dann erkennt er es IMHO automatisch, wenn B ne lib ist, das er die zu A zulinkt ....

    Oder (falls nur die libs linkst) in den linkereinstellungen zu Abhängigkeiten noch die B.lib hinzufügen !

    Dynamische libs (dll) geht aehnlich, wenn du eine importlib (B erzeugt lib und dll) verwendest.
    rein dynamischens binden (LoadLibrary) ist dann noch etwas komplizierter zu verstehen 🙂

    Grob verstanden ?

    Warum genau machst du unterschiedliche Projecte ?
    Nur wegen der Uebersichlichkeit ?

    Bibliotheken sind toll und vor allem mächtig.
    Aber Sie machen auch Aufwand (Wartung).
    Also wenn deine Bibliothek nur von einer Exe / dll jemals verwendet wird, dann ist der Aufwand/nutzen fraglich.

    Und ja manchmal ist es effizienter einfach nur die cpp dateien mit ins project zu nehmen ^^ Aber das ist sehr von der Situation abhaengig ....

    Ciao ...



  • Vielen Dank für deine Antwort, hat mir weiter geholfen.

    Ich komme eher aus dem Java Umfeld und da ist es üblich, ein Programm auf mehere Projekte aufzuteilen.
    Hatte also vor, es nur wegen der Übersichtlichkeit zu machen. Macht aber ja wohl für mich eher weniger Sinn.

    Wie sonst kann ich denn dann das Projekt besser strukturieren?
    Wenn alle Dateien einfach nur in einem Ordner liegen blickt man ja ziemlich schnell nicht mehr durch.

    Aber zumindest weiß ich jetzt, wie man eine statische Lib linkt 😃
    Deine Erklärung hat sich also gelohnt.



  • Wenn alle Dateien einfach nur in einem Ordner liegen

    Genau da iss vielleicht das verständniss-Problem 🙂

    C++ Sourcen und Dateisystem sind 2 volkommen unterschiedliche dinge 🙂
    Ob Dateien im selben verzeichniss stehen oder nicht, hat keinerlei relevanz fuer den compiler oder linker (mit paar kleinen ausnahmen)

    Für Visual Studio:
    Du kannst im VS im Project "Folder" erstellen (Haben nix mit Verzeichnissen im Dateisystem zu tun)
    Normal legt dir VS da immer "Source Files" "Includes" ""Ressources" usw an.
    Das kann man auch total umgestalten und auch Sub-Sub-Sub-Folder gehen da ^^

    Was in einem so nem "folder" steht, muss nicht im selben verzeichniss liegen ... so dass da ne freie Beziehung hasst.
    Also kannst auf dateisystemebene strukturieren und in VS in der Projektansicht.

    Wenn du komplexere, sprich riesige Projecte hasst, kommst auch ganz schnell zu dem Schluss, das die VS IDE allein auch zu unflexibel ist, und man sich da totklicken kann.
    Dann kommt der grosse auftritt der Buildgeneratoren (qmake, cmake, ant autoconf). Dann strukturierst sowieso total unabhaengig von der IDE im FS, und erzeugst automatisch deine vcprojs und sln's nur fuer den aktuellen Anendungsfall (fast nur noch debuggen)

    Die komplette Projectverwaltung geht dann ueber Scriptgesteuerte Configurationsdateien.

    Aber das nur am rande, bevor dich mit sowas beschaeftigst, solltest in c++ schon sattelfest sein ....

    Ciao ...



  • Als C++ Rookie habe ich diesem und zwei älteren Threads entnehmen können, dass meine Handhabung der Header- und cpp-Dateien einer Korrektur bedarf.

    Termite schrieb:

    *.c *.cpp:
    Implementierung von Funktionen und classen.

    *.h *.hpp:
    vordefinierungen / prototypen von funktionen und classen. Wird benötigt, damit der compiler mit in der c/c99-Datei implementierten Funktionen und classen umgehen kann. bzw. der C / CPP compiler ist relative dumm, er geht von oben nach unten durch, alles was er bisher an Klassen definitionen und funktionen nicht gesehen hat, kennt er nicht.

    (Dieses Zitat stammt übrigens aus 2008)

    Obwohl ich mich gerade nicht so klar daran gehalten habe, funktioniert bisher alles gut. Weil ich die cpp in der die main steckt nicht zu voll stopfen möchte, habe ich die meisten Funktionen ausgelagert und zwar in eine hpp-Datei, die ich dann includiere. Da nun weitere Funktionen dazukommen, denke ich an die nächste Datei und spätestens jetzt möchte ich das nicht zu falsch machen.

    Wenn ich an das alte TurboPascal zurückdenke, gab es da auch sowas wie eine Forward-Deklaration für Prozeduren und/oder Funktionen, so dass man im Deklarationsteil den Funktionskopf/Prozedurkopf in einer Zeile bekannt machte, den Code dafür aber erst weiter "unten" komplett definieren musste. So ähnlich fasse ich das nun auch auf, dass ich in einer Headerdatei z.B. schreiben würde:

    void meineFunktion1(int v1, char zeichen);
    
    int meineFunktion2(int x);
    

    In einer cpp-Datei würde dann die eigentliche Funktion komplett beschrieben werden. Soweit korrekt?
    Die Verwendung mehrerer cpp-Dateien in einem Projekt war ja bereits mehrfach nachgefragt worden, die Posts konnten mich aber nicht völlig schlau machen.
    Angenommen ich hätte in meinem Projekt eine main.cpp mit dem Hauptprogramm und m.E. auch mit den Includes der erforderlichen (Standard-) Headerdateien wie iostream, stdlib usw. Darüber hinaus würde ich nun eine eigene Headerdatei mit den Vordefinierungen meiner eigenen Funktionen erstellen, die meinetwegen molse.hpp heißen soll. Die Implementierung dieser Funktionen wird aufgeteilt in zwei Dateien, nämlich molse1.cpp und molse2.cpp.
    Wie bekomme ich es nun hin, dass die Teile des Projekts korrekt zusammengeführt werden können? Wiegesagt, im Moment habe ich die Implementierung in einer Headerdatei und das klappt. Danke vorab.



  • Molse schrieb:

    So ähnlich fasse ich das nun auch auf, dass ich in einer Headerdatei z.B. schreiben würde:

    void meineFunktion1(int v1, char zeichen);
    
    int meineFunktion2(int x);
    

    In einer cpp-Datei würde dann die eigentliche Funktion komplett beschrieben werden. Soweit korrekt?

    Das ist soweit korrekt.

    Es ist natürlich kein Problem, die in einer Headerdatei deklarierten Funktionen über mehrere cpp-Dateien verteilt zu implementieren und alles korrekt zusammenlinken (Es müssen halt alle Dateien Teil des VS-Projekts sein). Nur, wieso willst du das machen?



  • Zunächst geht es mir ja darum, die Headerdateien so zu benutzen wie es üblicherweise sein soll. In dem Buch, wo ich anfangs die Grundlagen nachgelesen habe, kam das für mich nicht so deutlich rüber.

    GPC schrieb:

    Nur, wieso willst du das machen?

    Für die Übersicht und thematische Trennung. Im Kleinen ausprobieren, was später im Großen funktionieren muss. Gelogen wäre: "Weil ich es kann" - ich will ja lernen und erfrage deshalb die mir unklaren Details.
    Um darauf noch einmal zurückzukommen, was ich im unteren Teil meines Posts als Beispiel brachte sind ja insgesamt 3 cpp-Dateien (die im Projekt integriert und als Quelldateien in der IDE zu sehen sind) und eine header-Datei.

    // main.cpp
    #include <iostream>
    #include <conio.h>
    #include <windows.h>
    
    #include "molse.hpp"
    
    // Kämen nun noch ...???
    #include "molse1.cpp"
    #include "molse2.cpp"
    
    int main()
    {
    

    ... oder includiert man molse1.cpp und molse2.cpp in die molse.hpp 😕

    Je mehr lesen, desto 😕



  • Also cpp-Dateien inkludiert man normalerweise nicht. Dein Beispiel sähe so aus:

    molse.hpp:

    #ifndef MOLSE_HPP
    #define MOLSE_HPP
    
    //Anstatt dem #ifndef-Block kannst du auch #pragma once machen, wenn du auf Windows unterwegs bist
    
    int addiere(int, int);
    int subtrahiere(int, int);
    
    #endif
    

    molse1.cpp:

    #include "molse.hpp"
    
    int addiere(int a, int b) {
      return a + b;
    }
    

    molse2.cpp:

    #include "molse.hpp"
    
    int subtrahiere(int a, int b) {
      return a - b;
    }
    

    main.cpp:

    #include "molse.hpp"
    
    int main(int argc, char** argv) {
      int x = addiere(1, 2);
      int y = subtrahiere(4, 3);
      return 0;
    }
    

    That's it 😉 Wenn du dich jetzt fragst, warum das funktioniert, solltest du dir vielleicht nochmal anschauen, was der Compiler und der Linker so machen 🙂



  • Danke GPC für deine Geduld und die anschaulische Darstellung.

    GPC schrieb:

    ... solltest du dir vielleicht nochmal anschauen, was der Compiler und der Linker so machen

    Keine Frage, dass das wieder und noch ein paar mal wieder angesagt ist. Die Zusammenhänge erschließen sich (leider) erst nach und nach.


Log in to reply