|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
t10ottoo Senior JLI'ler
Alter: 40 Anmeldedatum: 15.04.2004 Beiträge: 210 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 26.04.2006, 15:28 Titel: Probleme beim Inkludieren von Headerdateien |
|
|
Tach,
Ich habe ein sehr komisches Problem:
Ich habe drei Dateien in meinem Projekt:
main.cpp
Funktionen.cpp
Funktionen.h
main.cpp
Code: |
#include <conio.h>
#include <iostream>
#include "Funktionen.h"
#include "conioex.h"
using namespace std;
// Namen für die Tasten
#define CURS_UP 0x48
#define CURS_DOWN 0x50
#define CURS_LEFT 0x4B
#define CURS_RIGHT 0x4D
#define KEY_Z 0x7A
#define KEY_F 0x66
#define ESCAPE 0x1B
int main(int argc, char* argv[])
{
...
|
Geht noch weiter, ist aber nicht wichtig.
Funktionen.h
Code: | #ifndef FUNKTIONEN_H
#define FUNKTIONEN_H
void UP(int x, int y, bool zeichnen, bool farbe, char zeichen);
#endif |
Funktionen.cpp
Code: | #include <iostream>
#include "conioex.h"
using namespace std;
void UP(int x, int y, bool zeichnen, bool farbe, char zeichen)
{
[...]
} |
So, wie ihr seht, habe ich noch die conioex.h. Diese habe ich ausm Internet runergeladen, um in der Konsole farbig schreiben zu können und mit gotocx() den Cursor springen zu lassen. Wenn ich nur die main.cpp habe, klappt das auch wunderbar, aber nun wollte ich eben ein paar Funktionen extrahieren. Deswegen brauche ich die conioex.h in der main.cpp UND in der Funktionen.cpp.
Wenn ich aber kompiliere, kommt folgender Fehler:
Zitat: | Funktionen.obj : error LNK2005: _clrscr bereits in main.obj definiert |
Kommen also 14 Fehler, für jede Funktion, die in der conioex.h steht.
Hab schon alles Mögliche versucht, hab auch mal die conioex.h "richtig" ins Projekt eingebunden und auch in der Funktionen.cpp das mit ifndef und so gemacht, bringt alles nicht.
Ich hoffe, ihr könnt mir bei meinem kleinen Problem helfen
Gruß
Otti _________________ Meine kleine Projekte-Seite
Zuletzt bearbeitet von t10ottoo am 26.04.2006, 15:34, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
abc_d JLI Master Trainee
Alter: 34 Anmeldedatum: 27.01.2003 Beiträge: 615
Medaillen: Keine
|
Verfasst am: 26.04.2006, 15:30 Titel: |
|
|
Geht 2 mal "using namespace std;" überhaupt?
Lass das dumm und dähmlich bitte weg, in Zukunft antworte ich nicht mehr auf solche Threads. _________________ http://mitglied.lycos.de/sarti/linuxisevil.gif Linux is evil - get the fact.
Never touch a running System - der Systemling |
|
Nach oben |
|
|
t10ottoo Senior JLI'ler
Alter: 40 Anmeldedatum: 15.04.2004 Beiträge: 210 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 26.04.2006, 15:36 Titel: |
|
|
Zitat: | Lass das dumm und dähmlich bitte weg, in Zukunft antworte ich nicht mehr auf solche Threads. |
Habs geändert
BlackLordOfDragons hat Folgendes geschrieben: | Geht 2 mal "using namespace std;" überhaupt? |
Ich denke ja. Habs eben versucht, denn wenn ichs wegglasse, und anstelle von cout dann eben std::cout schreibe, kommen die gleichen Fehler wegen den Funktionen in der conioex.h. _________________ Meine kleine Projekte-Seite |
|
Nach oben |
|
|
fast hawk Senior JLI'ler
Anmeldedatum: 15.07.2005 Beiträge: 237 Wohnort: Freiburg Medaillen: Keine
|
Verfasst am: 26.04.2006, 16:21 Titel: |
|
|
Erstell mal einen Header in dem du alle includes machst und mach am anfang
CPP: | #pragma once
oder
#ifndef __WAS_DU_WILLST__
#define __WAS_DU_WILLST__
#endif
|
So wie ich das verstehe sagt der Compiler das du die conioex.h zweimal eingebunden hast aber was anderes fällt mir auch nicht ein woher hast du den die conioex.h weil bei der stl ist es auf jeden Fall egal wie oft man sie einbindet. _________________ Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann |
|
Nach oben |
|
|
t10ottoo Senior JLI'ler
Alter: 40 Anmeldedatum: 15.04.2004 Beiträge: 210 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 26.04.2006, 16:30 Titel: |
|
|
fast hawk hat Folgendes geschrieben: | Erstell mal einen Header in dem du alle includes machst und mach am anfang
CPP: | #pragma once
oder
#ifndef __WAS_DU_WILLST__
#define __WAS_DU_WILLST__
#endif
|
So wie ich das verstehe sagt der Compiler das du die conioex.h zweimal eingebunden hast aber was anderes fällt mir auch nicht ein woher hast du den die conioex.h weil bei der stl ist es auf jeden Fall egal wie oft man sie einbindet. |
Geht immer noch nicht, versteh es auch nicht.
Habe nun eine header.h erstellt, in der das drinsteht:
Code: | #ifndef HEADER_H
#define HEADER_H
#include <conio.h>
#include <iostream>
#include "Funktionen.h"
#include "conioex.h"
#endif |
In allen anderen Dateien habe ich alle #include's gelöscht und anstelle davon dann
Code: | #include "header.h" |
Gleicher Fehler:
Zitat: | Funktionen.obj : error LNK2005: _clrscr bereits in main.obj definiert |
Die conioex.h hab ich genau gesagt von der Berufsschule. Das komische ist ja, wenn ich nur eine Datei hab, wo ich die conioex.h brauche, dann klappt das ja. Also wenn du jetzt darauf aus bist, dass evtl was an der conioex.h nicht stimmt, das kann ich 100%ig ausschließen. _________________ Meine kleine Projekte-Seite |
|
Nach oben |
|
|
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 26.04.2006, 16:43 Titel: |
|
|
Kommt das nur mir so vor, oder 'inkludierst' (ich hasse dieses Wort) du hier irgendwie ziemlich wüst hin und her?
Die Deklarationen von Klassen/Funktionen gehören vor die Defintionen, also in die jeweilige *.cpp in den Kopf '#include "*.h"', und Fremddeklarationen gehören eigentlich auch in die Header eingebunden und nicht in die Source-Datei.
Außerdem brauchst du dann die 'conioex.h' nicht explizit in der 'main.cpp' nochmal linken, wenn du eben diese über die 'Funktionen.h' schon mitlinkst, hat zwar jetzt alles nicht unmittelbar mit der Problemlösung zutun, sollte aber helfen solche Probleme zu vermeiden. |
|
Nach oben |
|
|
t10ottoo Senior JLI'ler
Alter: 40 Anmeldedatum: 15.04.2004 Beiträge: 210 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 26.04.2006, 17:13 Titel: |
|
|
GreveN hat Folgendes geschrieben: |
Die Deklarationen von Klassen/Funktionen gehören vor die Defintionen, also in die jeweilige *.cpp in den Kopf '#include "*.h"', und Fremddeklarationen gehören eigentlich auch in die Header eingebunden und nicht in die Source-Datei.
Außerdem brauchst du dann die 'conioex.h' nicht explizit in der 'main.cpp' nochmal linken, wenn du eben diese über die 'Funktionen.h' schon mitlinkst, hat zwar jetzt alles nicht unmittelbar mit der Problemlösung zutun, sollte aber helfen solche Probleme zu vermeiden. |
Hab jetzt alle mal hin und her geschoben. Auch versucht, die Funktionsdeklaration direkt in die main zu machen, bringt alles nicht.
Wenn ich das include der conioex.h nicht in der main habe (ob obwohl ich Funktionen.h inkludiere und diese wiederum die conioex.h inkludiert), bekomme ich ne Meldung:
Zitat: | 'clrscr': Bezeichner wurde auch mit einer argumentbezogenen Suche nicht gefunden |
Dass er die ganzen Funktionen nicht finden.
Ich dreh mich nun irgendwie im Kreis.
Ich hab das mal hochgeladen, weil ich glaub, so bringt das nichts. Ich erhoffe mir davon, dass vlt. einer dann besser durch mein Problem durchsieht.
*klick*
Gruß
Otti _________________ Meine kleine Projekte-Seite |
|
Nach oben |
|
|
t10ottoo Senior JLI'ler
Alter: 40 Anmeldedatum: 15.04.2004 Beiträge: 210 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 27.04.2006, 13:42 Titel: |
|
|
Hi,
ich habe heut mal mein Berufsschullehrer gefragt, woran das liegen kann, dass ich die conioex.h nicht in zwei .cpp Dateien benutzen kann und habe ihm mein ganzes Problem geschildert.
Die Berufsschule hat nämlich die Definition, die in der conioex.c war, einfach in die conioex.h reinkopiert und so waren nun Deklaration und Definition der Funktion in der conioex.h. Somit brauchte keiner mehr die conioex.c. Damit wollten sie erreichen, dass die Schüler möglichst einfach die conioex.h inkludieren und dann gleich die Funktionen nutzen können.
Sie wollten also der Frage entgehen, die ich heut gestellt hab *g*
Naja, nun gehts auf jeden Fall, konntet ihr ja nicht wissen. Trotzdem Vielen Dank für eure Hilfe.
Gruß
Otti _________________ Meine kleine Projekte-Seite |
|
Nach oben |
|
|
xardias JLI Master
Alter: 38 Anmeldedatum: 28.12.2003 Beiträge: 804 Wohnort: Palo Alto, CA Medaillen: Keine
|
Verfasst am: 27.04.2006, 15:06 Titel: |
|
|
Ich wuerde mal sagen, da hat jemand grottig programmiert als er conioex erstellt hat |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 27.04.2006, 17:23 Titel: |
|
|
schade dass ich den thread hier jetz erst sehe , denn ich hatte vor kurzem genau dasselbe problem. Ich wollte das nur noch etwas mehr erläutern:
man mag zwar meinen, dass die präprozessor direktiven mit #ifndef usw. alles vom compiler abschirmen wenn das schon definiert ist; dem ist aber net so. Funktionsdefinitionen etc. werden trotzdem kompiliert, als Verdeutlichung:
CPP: | // Header-Datei
#ifndef DATEI
#define DATEI
// Funktionsdeklaration
void doSomething(bool para);
#endif |
und hier die entsprechende cpp-Datei: CPP: | #include "Datei.h"
// Funktionsdefinition
void doSomething(bool para)
{
...
} |
so kann man die headerdatei immer wieder inkludieren. Schreibt man aber Folgendes in den header CPP: | // Header-Datei
#ifndef DATEI
#define DATEI
// Funktionsdeklaration und (!) -definition
void doSomething(bool para)
{
...
}
#endif |
und lässt die cpp-Datei weg, so nützen die Direktiven nichts mehr beim öfteren inkludieren des Headers wird man auf einen Linkerfehler wie den, den otti oben gepostet hat, stoßen. daraus sollte man 2 Schlüsse ziehen:
1. Präprozessordirektive nützen nichts bei Definitionen
2. Definiere daher nie Funktionen etc. in headerdateien, denn die Folgen sind verzweifeltes Fehlersuchen und Ratlosigkeit. Für zegöhrige Definitionen von Deklarationen in Headern sind die Sourcedateien, d.h. die cpp-Dateien zuständig
Gruß DXer |
|
Nach oben |
|
|
t10ottoo Senior JLI'ler
Alter: 40 Anmeldedatum: 15.04.2004 Beiträge: 210 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 27.04.2006, 17:55 Titel: |
|
|
Vielen Dank für die Erläuterung DXer.
Was muss der Lehrer auch die Datei umschreiben :/ *g* _________________ Meine kleine Projekte-Seite |
|
Nach oben |
|
|
Dragon Super JLI'ler
Alter: 38 Anmeldedatum: 24.05.2004 Beiträge: 340 Wohnort: Sachsen Medaillen: Keine
|
Verfasst am: 27.04.2006, 18:07 Titel: |
|
|
DirectXer hat Folgendes geschrieben: | 2. Definiere daher nie Funktionen etc. in headerdateien, denn die Folgen sind verzweifeltes Fehlersuchen und Ratlosigkeit. Für zegöhrige Definitionen von Deklarationen in Headern sind die Sourcedateien, d.h. die cpp-Dateien zuständig |
Das stimmt so nicht ganz. Wie willst du eine Inline-Funktion in einer *.cpp definieren? Jetzt bin ich mal gespannt. _________________ Nur wenn man ein Ziel sieht, kann man es auch treffen.
___________
Mein Leben, Freunde und die Spieleentwicklung |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 27.04.2006, 20:00 Titel: |
|
|
Dragon hat Folgendes geschrieben: | DirectXer hat Folgendes geschrieben: | 2. Definiere daher nie Funktionen etc. in headerdateien, denn die Folgen sind verzweifeltes Fehlersuchen und Ratlosigkeit. Für zegöhrige Definitionen von Deklarationen in Headern sind die Sourcedateien, d.h. die cpp-Dateien zuständig |
Das stimmt so nicht ganz. Wie willst du eine Inline-Funktion in einer *.cpp definieren? Jetzt bin ich mal gespannt. |
nagut, irgendeiner musste diesen spezialfall ja rauskramen
ok, also für implizite inline-Funktionen gilt das net. Wer net weiß was das ist:
CPP: | class foo
{
public:
int getValue()
{
return 3;
}
}; |
wenn man also eine Funktionsdefinition innerhalb einer Klasse macht, dann gilt das für den Compiler als inline. Das ist also praktisch dafür dar, um sowas auszudrücken:
CPP: | inline int foo::getValue()
{
return 3;
} | wobei das vllt nicht kompiliert wird. Also, für diese Spezialfälle kann man die Definition in einer Headerdatei benutzen, aber sonst gilt das von vorher
Gruß DXer |
|
Nach oben |
|
|
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 28.04.2006, 11:31 Titel: |
|
|
Templates und static machen auf diese Weise auch nur Ärger, und zumindest Templates braucht man i.d.R. ja relativ oft. |
|
Nach oben |
|
|
Flow Junior JLI'ler
Alter: 42 Anmeldedatum: 13.09.2005 Beiträge: 57
Medaillen: Keine
|
Verfasst am: 04.05.2006, 17:21 Titel: |
|
|
Hi Leuts, hab ein Problem das hier scheinbar perfekt reinpasst, daher mach ich keinen neuen Thread auf. Trotzdem habe ich noch nicht alles so perefekt verstanden.
Hier mein Prob (ohne Code):
ich habe eine art zentrale allgemeine Header datei in meinem Projekt (general.h). Hier habe ich wichtige Makros, #defines und auch andere wichtige kleine funktionen, deren implementierung allerdings in der entsprechenden cpp datei sind. die komplette datei ist mit einem include-guard versehen von beginn der datei an bis zum ende.
die general.h #included fast alle klassen, die wiederum fast alle die general.h inkludieren, um ihrerseits auf sämtliche klassen zugreifen zu können. bisher klappte auch alles, nur habe ich plötzlich bei einer weiteren klasse, in der ich auf funktionen der general.h zugreife dutzende fehler, im prinzip sind es aber nur zwei verschiedene Fehlermeldungen:
// ED_FloatRandom() ist die Funktion die ich aufrufen möchte
- error C3861: "ED_FloatRandom": Bezeichner wurde nicht gefunden.
- ED_FloatRandom": Erneute Definition; vorherige Definition war "Ehemals unbekannter Bezeichner".
das an sich ist schon für mich nicht verständlich. was mir aber den grössten schuss ratlosigkeit gegeben hat, ist die tatsache, dass wenn ich besagten prototypen aus der general.h aus dem includeguard rausnehme und eine zeile VOR dessen Start einfüge funktioniert alles tadellos.
bei einer anderen klasse kam es sogar vor, dass er ein paar #defines nicht gefunden hat, woraufhin ich alle #defines und makros aus dem includeguard rausgenommen habe - so funktionierte das dann auch.
nur ist mein includeguard jetzt fast leer und es kann ja nicht der sinn und zweck des guards sein, jedesmal wenn ich fehlermeldungen habe, die entsprechende zeile aus dem guard herauszunehmen.
ein tief verwirrter antwortsuchender flow |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|