Forum: Compiler & IDEs Präprozessor: String für #include zusammenbauen


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

ich habe einen Haufen Header-Dateien, die Lookuptables enthalten, und 
deren Name identisch mit der darin definierten Variable ist. Ich will 
nur eine davon einbinden und auch einer Variablen zuweisen.

Sprich sie werden so genutzt:
1
//#include "abcdefg123.h"
2
//char *bitmap = &abcdefg123;
3
#include "abdefg123.h"
4
char *bitmap = &abdefg123;
5
//#include "abcdef123.h"
6
//char *bitmap = &abcdef123;
7
//#include "abcdefg124.h"
8
//char *bitmap = &abcdefg124;
9
   ...

Lieber wäre es, wenn ich mit Präprozessormagie nur eine Konstante 
anpassen müßte. Ungefähr so:
1
#define BITMAPFILE(NAME) "NAME ## .h"
2
#define BITMAP abdefg123
3
4
#include BITMAPFILE(BITMAP)
5
char *bitmap = &BITMAP;

Anscheinend scheint der Präprozessor das Include nur vor der 
Zeichenkettenoperation auszuführen.

Gibt es einen Trick, wie ich Variable + Header-Datei dennoch nur an 
einer Stelle einstellen kann?

Viele Grüße
W.T.

von Nop (Gast)


Lesenswert?

Walter T. schrieb:

> Gibt es einen Trick, wie ich Variable + Header-Datei dennoch nur an
> einer Stelle einstellen kann?

Das macht man normalerweise über #ifdefs, und Du kannst beim 
Compiler-Aufruf mit -DMY_STUFF oder -DMY_SWITCH=0/1/2/usw. das Richtige 
einblenden.

von Walter T. (nicolas)


Lesenswert?

Nop schrieb:
> Das macht man normalerweise über #ifdefs

Naja, #ifdefs würden dazu führen, dass ich neue neue Header-Datei 
anstelle an zwei Stellen nur noch an drei Stellen einpflegen müsste...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Eine #include-Direktive mit variablem Argument ist m.W. nicht möglich.
Du kannst das Include-File aber statt mit #include mit der Compiler-
Option -include einbinden und im Makefile, der Shell oder von wo immer
der Compiler aufgerufen wird, den Dateinamen variabel machen.

Edit:

Doch, #include ist natürlich auch mit einem Macro als Argument möglich. 
Ich habe da etwas durcheinander geschmissen.

: Bearbeitet durch Moderator
von A. S. (Gast)


Lesenswert?

1
#define BITMAP abdefg
2
3
#include <BITMAP.h> 
4
5
char *bitmap = &BITMAP;

falls Du " benötigst, entsprechen zusammenbauen lassen, mit """ und so.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Beispiel:
1
#define WHAT int
2
3
#define CONCAT2(a,b) a##b
4
#define CONCAT(a,b) CONCAT2(a,b)
5
#define SYS_HEADER <CONCAT(std,WHAT).h>
6
#include SYS_HEADER // --> #include <stdint.h>
7
8
#define STRINGY2(X) #X
9
#define STRINGY(X) STRINGY2(X)
10
#define USER_HEADER STRINGY(std WHAT.h)
11
#include USER_HEADER // --> #include "stdint.h"

von Nop (Gast)


Lesenswert?

Walter T. schrieb:

> Naja, #ifdefs würden dazu führen, dass ich neue neue Header-Datei
> anstelle an zwei Stellen nur noch an drei Stellen einpflegen müsste...

Nicht, wenn Du eine zentrale variable Headerdatei machst, in der per 
ifdef die Einblendungen gemacht werden, und Du diese zentrale 
Headerdatei dann ansonsten ohne ifdef inkludierst.

von Sub-Sub (Gast)


Lesenswert?

Die Datei heißt immer gleich befindet sich aber in unterschiedlichen 
Verzeichnissen. Über den compiler inklude Pfad  („-I..“wird dann die 
richtige geladen.

von Sub-Sub (Gast)


Lesenswert?

Meiner Ansicht nach wäre es am saubersten diese Lookup Tabelle innerhalb 
deines Build Prozesses zu generieren. Sie kommt dann in das Verzeichnis 
wo auch die generierten obj Dateien landen. Und zwar nur genau die eine, 
die für dein aktuelles Build die richtige ist.

von A. S. (Gast)


Lesenswert?

Walter T. schrieb:
> #define BITMAPFILE(NAME) "NAME ## .h"

hab jetzt keinen Compiler hier, aber funktioniert das nur in " " nicht 
(in < > dagegen schon? Wäre es so richtigt?
1
 #define BITMAPFILE(NAME) #NAME ".h"

von Wilhelm M. (wimalopaan)


Lesenswert?

Warum solche Klimmzüge: mit constexpr-Funktionen kannst Du doch die 
Lookup-Tabellen elegant im C++-Code selbst berechnen.

von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Johann L. schrieb:
> Beispiel:

Danke! Das war genau das, was ich gesucht habe.

Wilhelm M. schrieb:
> Warum solche Klimmzüge: mit constexpr-Funktionen kannst Du doch die
> Lookup-Tabellen elegant im C++-Code selbst berechnen.

Momentan erzeuge ich die Bitmap-Tabellen immer extern in Matlab. Im 
Build-Prozeß wäre natürlich super - allerdings kann ich mir das gerade 
nicht vorstellen, ohne dass der Build-Prozess auf externe Werkzeuge wie 
z.B. ImageMagick zugreift. Kannst Du das mal als Beispiel zeigen? Ich 
habe mal ein Roh-Bitmap angehängt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Walter T. schrieb:

> Wilhelm M. schrieb:
>> Warum solche Klimmzüge: mit constexpr-Funktionen kannst Du doch die
>> Lookup-Tabellen elegant im C++-Code selbst berechnen.
>
> Momentan erzeuge ich die Bitmap-Tabellen immer extern in Matlab. Im
> Build-Prozeß wäre natürlich super - allerdings kann ich mir das gerade
> nicht vorstellen, ohne dass der Build-Prozess auf externe Werkzeuge wie
> z.B. ImageMagick zugreift. Kannst Du das mal als Beispiel zeigen? Ich
> habe mal ein Roh-Bitmap angehängt.

Ich hatte oben nur etwas von Lookup-Tabelle gelesen und damit nicht das 
Zeichen von Bildern assoziiert.

Geht aber um das Umwandeln (nicht das Erzeugen) von BitMap-Daten, so 
kann man es schon so machen.

Bei den Bildern oder sagen wir besser Icons habe ich es so gelöst, dass 
ich die selbstverständlich mit einem Grafikprogramm erzeuge und dann als 
XBM (Header) speichere. Die XBM-Datei wird dann so inkludiert, wie sie 
ist. Das XBM-Format (es repräsentiert ja die Daten in einem 
char-C-Array) ist oft nicht das, was man als BitMap gebrauchen kann, und 
das kann man dann per constexpr-Funktion in das Zielformat umwandlen. 
Natürlich kann man Grafiken auch algorithmisch erzeugen, aber ich 
bezweifle, dass es irgendeine Grafik-Bibliothek gibt, die aus 
constexpr-Funktionen besteht bzw. dass es das ist, was Du machen 
möchtest.

von Markus F. (mfro)


Lesenswert?

Walter T. schrieb:
> Johann L. schrieb:
>> Beispiel:
>
> Danke! Das war genau das, was ich gesucht habe.
>

Das ist zwar "bewundernswert smarte Präprozessor-Magie", aber doch ein 
Krampf, wenn man's pflegen und sich immer wieder neu eindenken muss.

Für die constexpr-Logik gilt nach meinem Geschmack Ähnliches.

M.E. gehört solcherlei Preprocessing ins Makefile und sonst nirgendwo 
hin. Dort würde zumindest ich danach suchen.

von 43222342 (Gast)


Lesenswert?

ich mache das mit texten so ...

in dem textfile ist dann nur formatiert der inhalt des arrays
1
{ 
2
   "text"
3
}


im code dann
1
const char *sprache[]={
2
#include "textfile.txt"
3
}

das klappt auch mit anderen sachen. nur muss die zu includierende datei 
entsprechend formatiert sein.


oder du machst ein binary draus und verknüpfst das über den linker

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.