Forum: PC-Programmierung Probleme mit Preprocessor.


von includer (Gast)


Lesenswert?

Hallo

Ich möchte in einem Projekt, welches auf verschiedenen Plattformen 
läuft, unterschiedliche #include-Anweisungen tätigen und einige 
Funktionen anders implementieren (die Funktionsdeklaration im H-File 
bleibt allerdings gleich).
Wie gehe ich da am besten vor?
Was ich versucht habe:
im main.h (welches in main.c als erstes inlcudet) wird habe ich 
folgendes:

#define uP 1
#define PC 2

/*Je nachdem welches das Targetsystem ist:*/
#define TARGETSYSTEM uP

dann habe ich in den je nach Plattform speziellen #includes so gelöst:

#if TARGETSYSTEM == PC
  #include ....
  #include ....
#elif TARGETSYSTEM == PC
  #include ....
#endif

Analog dazu habe ich das auch in den jeweiligen .c-Files gemacht, wo die 
implementation sich unterscheidet.
In VisualStudio funktioniert das auch wunderbar. Aber in der 
Entwicklungsumgebung für den uP will er immer alles includen.
Was muss ich beachten? Ich dachte, dass wenn die Konstanten ganz am 
Anfang des main.c durch #include "main.h" definiert sind es 
funktionieren sollte. Tut es aber nicht...
Was mache ich falsch? Ist das nicht die übliche Vorgehensweise?
Vielen Dank für die Hilfe

von Karl H. (kbuchegg)


Lesenswert?

includer wrote:

> Was mache ich falsch? Ist das nicht die übliche Vorgehensweise?
> Vielen Dank für die Hilfe

Mit solche Vergleichsorgien bin ich immer sehr vorsichtig.
Wie du anscheinend slebst schon gesehen hast, kann da alles
mögliche passieren.
1
#define PC       // uncomment for PC usage
2
// #define µC    // uncomment for µC usage
3
4
5
#ifdef PC
6
  #include "dies und das.h"
7
  #include "das auch noch.h"
8
#endif
9
10
#ifdef µC
11
  #include "die einfache Version.h"
12
#endif

Das kann jeder Präprozessor und da die meisten Compiler Definements
auch über die Commandline akzeptieren, lässt sich die Auswahl dann
auch gut in ein Makefile einbauen.

von Bernhard M. (boregard)


Lesenswert?

#if TARGETSYSTEM == PC
  #include ....
  #include ....
#elif TARGETSYSTEM == PC

das ist ja beides das gleiche, meinst Du

#if TARGETSYSTEM == PC
  #include ....
  #include ....
#elif TARGETSYSTEM == uP

von includer (Gast)


Lesenswert?

Ja, das habe ich falsch abgeschrieben, es hat trotzdem nicht sollen 
sein...
Aber Karl heinz hats wieder mal geschafft mir die Augen zu öffnen. Ich 
habe ein Flair, alles kompliziert und in der Folge daraus auch falsch zu 
machen.
Jetzt funktionierts. Gruss und Danke

von includer (Gast)


Lesenswert?

So, jetzt brennts an der nächsten Stelle, ich hoffe zum letzten Mal:
Ich habe es wie oben beschrieben geschafft, unter VisualStudio das Ding 
zu kompilieren und laufen zu lassen. Nachdem ich (nur) den Vorschlag von 
Karl heinz umgesetzt habe, kommt nun das nächste Problem:
Es gibt folgende Linker-Fehler: error LNK2019: unresolved external 
symbol...

in den H-Dateien sind die Deklarationen als extern int 
funktionsname(blabla); eingetragen, und #include anweisungen sollten 
auch stimmen (diese sieht imho der Linker auch nicht mehr). Das sollte 
daher stimmen.
Woher kommen die dann plötzlich?
2 Sachen sind daran interessant:
1. wenn ich so eine Funktion die beim Linken anscheinend unbekannt ist 
in VisualStudio mit der rechten Maustaste anklicke kann ich mit Go to 
Definition in das entsprechende File an diese Stelle springen. Er 
scheints also schon zu finden.
2. es sind nur die Funktionen zweier H-Files, aber ich kann keinen 
unterschied feststellen, der den Fehler erklären könnte?!
Woran könnte das liegen?

von Karl H. (kbuchegg)


Lesenswert?

includer wrote:

> Es gibt folgende Linker-Fehler: error LNK2019: unresolved external
> symbol...

Der Linker konnte die entsprechende Funktion nicht finden.

> in den H-Dateien sind die Deklarationen als extern int
> funktionsname(blabla); eingetragen

OK. Die interessieren den Linker aber eigentlich nicht.
Die sind nur für den Compiler interessant, damit der weiß,
das es diese Funktion tatsächlich irgendwo gibt und das ein
Funktionsaufruf dieser Funktion nicht einfach nur ein Tippfehler
war.

Für den Linker ist nur interessant: Welche Funktion wird aufgerufen
und gibt es diese Funktion in dem Wust an Object Files überhaupt.

> Woher kommen die dann plötzlich?

Weil du den Linker das Object File nicht übergeben hast, in
dem die Implementierung dieser Funktion steckt.

> 2 Sachen sind daran interessant:
> 1. wenn ich so eine Funktion die beim Linken anscheinend unbekannt ist
> in VisualStudio mit der rechten Maustaste anklicke kann ich mit Go to
> Definition in das entsprechende File an diese Stelle springen. Er
> scheints also schon zu finden.

Das hat nichts zu sagen.
Wenn ich meine Festplatte durchsuchen lasse, finden sich auch
unzählige Funktionen, die nicht zu irgendeinem Projekt gehören.

von includer (Gast)


Lesenswert?

Hmmm....
Komisch nur, dass vorher die Dinger gefunden wurden.
Die Object-Files (sofern diese .obj-Endung haben) liegen von allen 
Kompilaten im gleichen Verzeichnis (ich kann sie löschen und nach dem 
Kompilieren sind sie wieder dort).
Einige Funktionen findet der Linker, einige nicht: von 4 .c bzw. 
.h-Files findet er die Funktionen in 2 Fällen, in den anderen 2 nicht. 
Da komme ich nicht mehr weiter, v.a. weil sich die nicht wirklich 
unterscheiden...

ratlosbin

von includer (Gast)


Lesenswert?

So, hab den Fehler gefunden. Liegt nicht am Linker, sondern doch an den 
Präprozessor-Dingern.
Obwohl ich in main.h den Vorschlag von Karl heinz drin habe, scheinen 
die define auf die nachher includierten Files keinen Einfluss zu haben. 
Er meint sie seien nicht definiert. Natürlich wird die Deklaration
[c]define PC[\c]
vor dem includen der Files, welche auf
[c]#ifdef PC[\c]
testen, vorgenommen.

Was kann man da tun? Ist die include-Reihenfolge nicht so wie man sie 
hinschreibt? Woran kann das sonst noch liegen?

von includer (Gast)


Lesenswert?

Oh, vorsicht '\' != '/'....;)
Ich werde schusselig aufs alter

von includer (Gast)


Lesenswert?

und den # vor define auch vergessen tststs, in meinem Programm stehts 
auf jeden Fall drin!

von Karl H. (kbuchegg)


Lesenswert?

includer wrote:
> So, hab den Fehler gefunden. Liegt nicht am Linker, sondern doch an den
> Präprozessor-Dingern.
> Obwohl ich in main.h den Vorschlag von Karl heinz drin habe, scheinen
> die define auf die nachher includierten Files keinen Einfluss zu haben.
> Er meint sie seien nicht definiert. Natürlich wird die Deklaration
> [c]define PC[\c]
> vor dem includen der Files, welche auf
> [c]#ifdef PC[\c]
> testen, vorgenommen.
>
> Was kann man da tun? Ist die include-Reihenfolge nicht so wie man sie
> hinschreibt? Woran kann das sonst noch liegen?

Doch. Ist so.

Hmm. Hast du schon mal einen "Rebuild All" gemacht. Manchmal
baut der Makefilegenerator im Visual Studio einfach nur Müll.
Ein Rebuild All (bzw. ein komplettes Löschen des Debug bzw. Release
Verzeichnisses) hat schon so manchen unerklärlichen Fehler
aus der Welt geschafft.

von includer (Gast)


Lesenswert?

Hallo!

Danke dass du noch nicht aufgegeben hast.
Rebuild All gibts nicht (habe eine Deutsch Version), habe aber unter 
Buld alles Kombinationan von Clean Project Rebuild Project etc. 
probiert. Ohne Erfolg.
Lustigerweise funktionierts auch in der IDE des uP nicht. Findet die 
selben Dinger nicht. Also liegts wohl irgendwie doch am Code und nicht 
an der IDE.
Was ich noch festgestellt habe, was allerdings nicht zum Problemlösen 
beitragen dürfte:
VisualStudio hinterlegt Code, welcher vom Preprocessor weggeschmissen 
wird grau. Nach dem
1
#ifdef PC

ist der Code grau bis
1
#endif
wenn ich aber wieder die Klickibunti rechte Maustaste auf PC mache und 
"Go to Definition" klicke, dann springt er schön brav in main.h und 
zeigt die Definition an...
Ich werd wahnsinnig!

von Karl H. (kbuchegg)


Lesenswert?

includer wrote:

> Ich werd wahnsinnig!

Vergiss das Code Aufsuchen in der IDE. Das sagt nichts, aber auch
gar nichts aus.

Wenn alle Stricke reissen: Pack mal alles in ein Zip File und
lade es hoch.

von includer (Gast)


Lesenswert?

Habs immer noch nicht geschafft, allerdings möchte ich nicht das ganze 
Ding hochladen, da es sich um einen Teil einer Studienarbeit handelt...

von Uhu U. (uhu)


Lesenswert?

Kann es sein, daß das Projekt noch nie auf der Maschine compiliert 
wurde, auf der du es versuchst?

Wenn ja, könnte ein übles Problem mit der VC-IDE in Frage kommen:

- auf dem System, auf dem sich das Teil compilieren läßt, wurden
  Include-Pfade in die Projekt-Properties eingetragen, sondern unter
  Tools | Options | Projects and Solutions | VC++ Directories |
  Include files.
  Das hat zur Folge, daß essentiell notwendige Einstellungen nicht
  Bestandteil des Projektes, sondern der IDE sind.

- Auf deinem System fehlen diese Einträge entweder, oder sind in einer
  anderen Reihenfolge.

Die Folge sind nur zu oft Probleme, wie du sie im Moment hast.
Deswegen meine Faustregel: Finger weg von den Pfadeinstellungen unter 
Tools!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.