amiga-news DEUTSCHE VERSION
.
Links| Forums| Comments| Report news
.
Chat| Polls| Newsticker| Archive
.

amiga-news.de Forum > Programmierung > GCC/G++ Anfängerprobleme die 2. [ - Search - New posts - Register - Login - ]

-1- [ - Post reply - ]

2005-02-02, 08:22 h

Reth
Posts: 1858
User
Schönen Tach nochmals,

hab mal wieder Probleme mit besagten Tools.

Das Compilieren der einzelnen Klassen aus dem Makefile heraus klappt hervorragend, die Objekte werden erzeugt.
Aber dann versagt das Linken.

An einigen Stellen meint ld: undefined reference auf asl und graphics.
Das kann daran liegen, dass ich im Code vergessen habe die Libraries zu öffnen, aber deren Funktionen verwende. Das lässt sich beheben.

Was ich aber nicht verstehe ist folgendes:

Ich habe 2 Klassen A und B. A wird in B verwendet, es soll ein Objekt vom Typ A zur Laufzeit erzeugt werden. A hat einen parameterlosen Konstruktor und einen mit Parameteren. Der parameterlose Konstruktor ist dafür, dass der Compiler zufrieden ist, da bei C++ anscheinend beim Erstellen eines Objektes welches weitere Objekte erzeugt (in meinem Fall beim Erstellen von B) immer auch der Konstruktor der inneren Objekte gerufen wird (hab ich aus einem umfassenden C++ Tutorial), so dass zur Compilezeit schon geprüft wird. In meinem Fall wird in B ein Objekt vom Typ A erzeugt (wenn ichs gerad genau weiss, sogar im Konstruktor von B), darum prüft der Compiler, ob es von A einen paramterlosen Konstruktor gibt, da ich A nicht mit : hinter den Konstruktoraufruf von B gesetzt habe.

Soweit so gut. Nun sind beide Klassen in eigenen Headerdateien deklariert, wobei der Header von B den von A inkludiert und das Sourcefile von B den Header von B (das Sourcefile von A natürlich den Header von A).
Damit ist der Compiler zufrieden, kennt alles und erzeugt Objektfiles.
Der Linker jedoch mosert rum, dass es in B bei text+0x40 (oder so) eine "undefined reference to A()" gibt und bei text+0x41 eine "undefined reference to A(param1, param2, ...).
Warum das denn? Was fehlt da noch? muss ich ausser der -I Option beim g++ noch ne Option beim Linker angeben, wo er die Objektdateien findet?
Muss man libamiga oder ähnliches angeben, damit der die OS-Libraries u.dgl. findet?

Fragen über Fragen.

Wenn die Fragen zu blöd, lächerlich, offensichtlich etc. sind, wäre ich auch für ein paar weiterhelfende Links auf Tutorials, FAQ, häufige Probleme mit GCC und Konsorten, etc. dankbar!

Ciao

[ - Answer - Quote - Direct link - ]

2005-02-02, 10:41 h

Solar
Posts: 3680
User
Zu wenig Informationen.

Wie sieht Deine Kommandozeile aus, mit der Du den Fehler reproduzierst?

Und... "innere Objekte" und "erzeugen von A im Konstruktor" riecht ziemlich faul. Kannst Du den fraglichen Quellcode hier mal posten?

[ - Answer - Quote - Direct link - ]

2005-02-02, 19:03 h

Reth
Posts: 1858
User
Zitat:
Original von Solar:
Zu wenig Informationen.

Wie sieht Deine Kommandozeile aus, mit der Du den Fehler reproduzierst?


Einfach nur make aus dem GoldEd mittels Rexx Script. Das Makefile sieht so aus:

projectPath = <Pfad<

ScreenMode : ScreenModeRequestC.o ScreenModeDataC.o ScreenModeHookC.o ScreenMode.o
g++ -I $(projectPath) -o SCreenMode ScreenModeRequestC.o ScreenModeHookC.o ScreenMode.o

ScreenMode.o : ScreenMode.cc ScreenModeRequestC.h ScreenModeHookC.h
g++ -I $(projectPath) -c ScreenMode.cc
ScreenModeRequestC.o : ScreenModeRequestC.cc ScreenModeRequestC.h ScreenModeDataC.h
g++ -I $(projectPath) -c ScreenModeRequestC.cc
ScreenModeDataC.o : ScreenModeDataC.cc ScreenModeDataC.h
g++ -I $(projectPath) -c ScreenModeDataC.cc
ScreenModeHookC.o : ScreenModeHookC.cc ScreenModeHookC.h Constants.h
g++ -I $(projectPath) -c ScreenModeHookC.cc

clean :
delete ScreenModeHookC.o ScreenModeDataC.o ScreenModeRequestC.o ScreenMode.o

Zitat:
Und... "innere Objekte" und "erzeugen von A im Konstruktor" riecht ziemlich faul. Kannst Du den fraglichen Quellcode hier mal posten?

Hier der Header von besagter Klasse A:

#include <exec/types.h>

class ScreenModeDataC
{
public:
ScreenModeDataC();
ScreenModeDataC(ULONG width, ULONG height, ULONG depth, ULONG id);

ULONG getWidth() {return displayWidth;};
ULONG getHeight(){return displayHeight;};
ULONG getDepth() {return displayDepth;};
ULONG getID() {return displayID;};

private:
ULONG displayWidth, displayHeight, displayDepth, displayID;
};

und hier der von B:

#include <utility/hooks.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>

#include <ScreenModeDataC.h>

class ScreenModeRequestC
{
public:
ScreenModeRequestC(UWORD minWidth, UWORD minHeight, UWORD minDepth, UWORD maxWidth, UWORD maxHeight, UWORD
maxDepth, struct Hook *filterFunc);

ScreenModeDataC getScreenModeData();

private:
ScreenModeDataC scrMDData;
};


Implementierung von A:

#include <ScreenModeDataC.h>

ScreenModeDataC::ScreenModeDataC()
{
displayWidth = 0;
displayHeight= 0;
displayDepth = 0;
displayID = 0;
}

ScreenModeDataC::ScreenModeDataC(ULONG width, ULONG height, ULONG depth, ULONG id)
{
displayWidth = width;
displayHeight= height;
displayDepth = depth;
displayID = id;
}

und von B:

#include <libraries/asl.h>
#include <clib/asl_protos.h>

#include <ScreenModeRequestC.h>

ScreenModeRequestC::ScreenModeRequestC(UWORD minWidth, UWORD minHeight, UWORD minDepth, UWORD maxWidth, UWORD maxHeight,
UWORD maxDepth, struct Hook *filterFunc)
{
struct ScreenModeRequester *scrMDRQ = (struct ScreenModeRequester *)AllocAslRequestTags(ASL_ScreenModeRequest,
ASLSM_InitialInfoOpened, TRUE,
ASLSM_DoWidth, TRUE,
ASLSM_DoHeight, TRUE,
ASLSM_DoDepth, TRUE,
ASLSM_DoOverscanType, TRUE,
ASLSM_DoAutoScroll, TRUE,
ASLSM_MinWidth, minWidth,
ASLSM_MaxWidth, maxWidth,
ASLSM_MinHeight, minHeight,
ASLSM_MaxHeight, maxHeight,
ASLSM_MinDepth, minDepth,
ASLSM_MaxDepth, maxDepth,
ASLSM_FilterFunc, filterFunc,
ASLSM_PopToFront, TRUE,
ASLSM_Activate, TRUE, TAG_DONE);

if ((scrMDRQ != NULL) && (AslRequestTags(scrMDRQ, TAG_END)))
{
scrMDData = ScreenModeDataC(scrMDRQ->sm_DisplayWidth, scrMDRQ->sm_DisplayHeight, scrMDRQ->sm_DisplayDepth,
scrMDRQ->sm_DisplayID);
}
}

ScreenModeDataC ScreenModeRequestC::getScreenModeData()
{
return scrMDData;
}


Wie gesagt, es fehlen das Öffnen der Libs und noch ein paar andere Klassen. Aber um die beiden gehts erstmal.

Ausgabe von make:

ScreenModeRequestC.o(.text+0x40): undefined reference to 'ScreenModeDataC::ScreenModeDataC(void)'
ScreenModeRequestC.o(.text+0x14a): undefined reference to 'ScreenModeDataC::ScreenModeDataC(unsigned long, unsigned long, unsigned long, unsigned long)'


Keine Ahnung was fehlt? Das Einzige, was ich mir vorstellen kann, ist dass er die Objektdateien nicht findet! Oder isses was anderes?

[ - Answer - Quote - Direct link - ]

2005-02-02, 21:34 h

Reth
Posts: 1858
User
Hab das Problem gelöst, es fehlte ScreenModeData.o im makefile.

Was muss ich denn angeben, damit er die Objektdateien der Amigalibs findet? Diese namentlich im makefile?

Danke schon mal für die bisherigen und evtl. weiteren Hilfen!
Ciao

[ - Answer - Quote - Direct link - ]

2005-02-02, 21:48 h

Dr_X
Posts: 24
User

LDFLAGS = -L. -lamiga

--
(Amiga) µA1-C in A1000 Gehäuse aber mit Amiga OS4.0 pre

[ - Answer - Quote - Direct link - ]

2005-02-03, 07:59 h

Reth
Posts: 1858
User
Zitat:
Original von Dr_X:

LDFLAGS = -L. -lamiga

--
(Amiga) µA1-C in A1000 Gehäuse aber mit Amiga OS4.0 pre


Danke! Schreib ich das einfach so ins Makefile oben rein, oder kommt das als Option an den G++ Aufruf?


[ - Answer - Quote - Direct link - ]

2005-02-03, 09:16 h

gni
Posts: 1106
User
Zitat:
Dr_X:
LDFLAGS = -L. -lamiga

Wozu soll "-L." gut sein? Und wenn es um den GCC von GG geht, da wird automatisch mit -lamiga gelinkt.

[ - Answer - Quote - Direct link - ]

2005-02-03, 09:28 h

gni
Posts: 1106
User
Zitat:
Reth:

und hier der von B:

#include <utility/hooks.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>

Die asl Header brauchts Du hier nicht.
Zitat:
ScreenModeDataC getScreenModeData();
Dir ist hoffentlich bewußt, daß Du hier ein Objekt zurückgibst. Vermutlich solltest Du ein const Referenz verwenden.
Zitat:
ScreenModeRequestC::ScreenModeRequestC(
if ((scrMDRQ != NULL) && (AslRequestTags(scrMDRQ, TAG_END)))
}

Sowas in einem Konstruktor zu machen ist unklug, zumal Du keine Exception benutzt. Du erzeugst also ein Objekt, das unbenutzbar ist.

[ - Answer - Quote - Direct link - ]

2005-02-03, 10:38 h

Reth
Posts: 1858
User
Danke für Deine Tips!

Noch ein paar Fragen.

Zitat:
Original von gni:
Zitat:
Reth:
ScreenModeDataC getScreenModeData();

Dir ist hoffentlich bewußt, daß Du hier ein Objekt zurückgibst. Vermutlich solltest Du ein const Referenz verwenden.

Das ist ne Sache, die ich an C++ noch nicht ganz verstanden habe. Zeiger unterscheiden sich ja von Referenzen, aber der Unterschied ist mir nicht so ganz klar. Zeiger sind ne Datenstruktur, mit der man z.B. auch rechnen kann, Referenzen sind ...?

Bei Java ist das einfacher, da sind alle Objekte Zeiger (ausser Strings).

Gibts denn ein gutes C++ Standardwerk, wo man die ganzen Sachen schön differenziert erklärt bekommt, auch Exceptions in C++?
Soviel weiss ich, dass wenn man in C++ ein Objekt einer Methode übergibt, eine Kopie des Objektes angelegt wird.

Bei Referenzen ist mir das nicht so ganz klar. Wenn ich nun ein Objekt in einer Klasse erzeuge und eine Referenz darauf einer aufrufenden Klasse zurückgebe. Wie lang ist diese Referenz dort dann gültig? Wass passiert mit der Referenz in der aufrufenden Klasse, wenn das Objekt, aus dem die Referenz zurückgegeben wurde out of scope geht?

Zitat:
Zitat:
ScreenModeRequestC::ScreenModeRequestC(
if ((scrMDRQ != NULL) && (AslRequestTags(scrMDRQ, TAG_END)))
}

Sowas in einem Konstruktor zu machen ist unklug, zumal Du keine Exception benutzt. Du erzeugst also ein Objekt, das unbenutzbar ist.

Darum hab ich auch schon nachgedacht, einen Zeiger auf das Objekt zurückzugeben, welcher dann NULL ist, wenn das Objekt nicht richtig erstellt werden konnte!

[ - Answer - Quote - Direct link - ]

2005-02-03, 20:43 h

Holger
Posts: 8116
User
Zitat:
Original von Reth:
Bei Java ist das einfacher, da sind alle Objekte Zeiger (ausser Strings).

Falsch. In Java sind alle Objekte Referenzen. Und Strings bilden keine Ausnahme.
Zitat:
Bei Referenzen ist mir das nicht so ganz klar. Wenn ich nun ein Objekt in einer Klasse erzeuge und eine Referenz darauf einer aufrufenden Klasse zurückgebe. Wie lang ist diese Referenz dort dann gültig?
So lange wie Du sie benutzt. Wenn Du sie z.B. einer Variablen zuweist, dann ist sie genauso lange gültig, wie diese Variable gültig ist. Steckst Du sie direkt in einen anderen Methoden-/Funktionsaufruf, ist sie halt für die Dauer dieses Aufrufs gültig.
Zitat:
Was passiert mit der Referenz in der aufrufenden Klasse, wenn das Objekt, aus dem die Referenz zurückgegeben wurde out of scope geht?
Wo das Objekt herkommt spielt keine Rolle. Solange die Referenz im scope ist, ist sie auch gültig.
Ist doch gar nicht so schwer. Ist doch eigentlich genau so wie in Java :D

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Answer - Quote - Direct link - ]


-1- [ - Post reply - ]


amiga-news.de Forum > Programmierung > GCC/G++ Anfängerprobleme die 2. [ - Search - New posts - Register - Login - ]


.
Masthead | Privacy policy | Netiquette | Advertising | Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved.
.