Hinweis: Das Forum wird geschlossen! Neue Registrierungen sind nicht mehr möglich!

 Zurück zu Pro-Linux   Foren-Übersicht   FAQ     Suchen    Mitgliederliste
c präprozessor

 
Neuen Beitrag schreiben   Auf Beitrag antworten    Pro-Linux Foren-Übersicht -> Programmieren - C
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
blubb
Gast





BeitragVerfasst am: 24. Nov 2004 18:28   Titel: c präprozessor

tag auch,

folgendes problem:
habe eine string_defs.h in der einige deklarationen stehen, jetzt habe ich auch eine main.c (wow ;D) und eine action_funcs.c etc.
in beiden habe ich drinnen stehen:

Code:

#ifndef STRING_DEFS_H
#include "string_defs.h"
#endif


in der string_defs.h steht:
Code:

#ifndef STRING_DEFS_H
#define STRING_DEFS_H
... code ...
#endif


beim compilieren meckert er aber das die strings mehrfach deklariert werden.
weis wer wo das problem liegt? :/

blubb
 

JochenAlsGast
Gast





BeitragVerfasst am: 25. Nov 2004 9:08   Titel:

Das sieht mir nicht unbedingt falsch aus. Höchsten dass das #ifndef/#endif um das #include herum überfüssig ist. Zum Testen habe ich mal eben was zusammen gepröttelt:
Code:
/* Header */

#ifndef A_H
#define A_H

#define HALLO "Hallo Welt\n"

#endif
Und dazu:
Code:
/* Source */

/* Erstes Mal: Alles definieren */
#include "a.h"
/* Zweites Mal: Ist schon definiert, #ifndef A_H darf nicht mehr greifen */
#include "a.h"

#include <stdio.h>

int main (void) {
        printf (HALLO);
        exit (0);
}
Wenn ich die als a.h und a.c abspeichere und mittels "make a" übersetze, erhalte ich keine Fehlermeldungen. Ich würde mal tippen, das der Fehler bei Dir irgendwo anders liegt...?

Jochen
 

blubb
Gast





BeitragVerfasst am: 25. Nov 2004 10:39   Titel:

hmm,

ich poste mal die praeprozessor anweisungen von jedem file und den gcc fehler.
string_defs.h:
Code:


#ifndef STRING_DEFS_H
#define STRING_DEFS_H

static struct part_table
{

      char swap[30];
      char root[30];
      char fs[15];
}hdd_info;


char *main_choices[] =
{
   "1) Keymap",
     "2) Swap partition",
...

action_funcs.c

Code:
#include <errno.h>
#include <dirent.h>
#include "string_defs.h"
#include "action_funcs.h"

set_funcs.c:

Code:
#include "string_defs.h"
#include "set_funcs.h"
#include <ncurses.h>


und die letzte; window_funcs.c
Code:
#ifndef WINDOW_FUNCS_H
#define WINDOW_FUNCS_H
#include <stdio.h>
#include <ncurses.h>
#include "string_defs.h"


also ich denk von den header files her sollte alles passen, ich checks auch nich... ich kann auch mal die komplette string_defs.h posten wenn das was bringt...

blubb
 

jochen
prolinux-forum-admin


Anmeldungsdatum: 14.01.2000
Beiträge: 699
Wohnort: Jülich

BeitragVerfasst am: 25. Nov 2004 10:42   Titel:

Der gcc-Fehler fehlt noch.

Jochen
_________________
Die grösste Lüge der EDV? "Mal eben..."
 
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen

blubb
Gast





BeitragVerfasst am: 25. Nov 2004 17:04   Titel:

sry, voll verpeilt Very Happy
Code:

main.o(.data+0x0): multiple definition of `main_choices'
action_funcs.o(.data+0x0): first defined here
main.o(.data+0x1c): multiple definition of `keymap_choices'
action_funcs.o(.data+0x1c): first defined here
main.o(.data+0x2c): multiple definition of `fs_choices'
action_funcs.o(.data+0x2c): first defined here
main.o(.data+0x40): multiple definition of `info_choices'
action_funcs.o(.data+0x40): first defined here
main.o(.data+0x60): multiple definition of `welcome_choices'
action_funcs.o(.data+0x60): first defined here
set_funcs.o(.data+0x0): multiple definition of `main_choices'
action_funcs.o(.data+0x0): first defined here
set_funcs.o(.data+0x1c): multiple definition of `keymap_choices'
action_funcs.o(.data+0x1c): first defined here
set_funcs.o(.data+0x2c): multiple definition of `fs_choices'
action_funcs.o(.data+0x2c): first defined here
set_funcs.o(.data+0x40): multiple definition of `info_choices'
action_funcs.o(.data+0x40): first defined here
set_funcs.o(.data+0x60): multiple definition of `welcome_choices'
action_funcs.o(.data+0x60): first defined here
window_funcs.o(.data+0x0): multiple definition of `main_choices'
action_funcs.o(.data+0x0): first defined here
window_funcs.o(.data+0x1c): multiple definition of `keymap_choices'
action_funcs.o(.data+0x1c): first defined here
window_funcs.o(.data+0x2c): multiple definition of `fs_choices'
action_funcs.o(.data+0x2c): first defined here
window_funcs.o(.data+0x40): multiple definition of `info_choices'
action_funcs.o(.data+0x40): first defined here
window_funcs.o(.data+0x60): multiple definition of `welcome_choices'
action_funcs.o(.data+0x60): first defined here
collect2: ld returned 1 exit status
 

jochen
prolinux-forum-admin


Anmeldungsdatum: 14.01.2000
Beiträge: 699
Wohnort: Jülich

BeitragVerfasst am: 25. Nov 2004 18:15   Titel:

Ah, jetzt wird es klarer.

Der C-Präprozessor hat damit nix zu tun. Die Fehlermeldungen stammen vom Linker, der in unterschiedlichen Object-Files gleichnamige Data-Objekte findet.

Der C-Compiler unterscheidet zwischen der Deklaration und der Definition einer Variablen. "Deklaration" heisst, Du sagst Deinem Compiler, dass es irgendwo eine Variable diesen Namens gibt. Deklarationen kannst Du so viele haben wie Du willst. "Definition"dagegen bedeutet, dass der Compiler für diese Variabe auch tatsächlich Speicherplatz bereitstellen soll.

In Deiner Header-Datei stehen Definitionen, d.h. Du verlangst, dass eine Variable diesen Namens angelegt und Speicherplatz dafür reserviert wird. Jede .c-Datei, die dieses Header-File #includet, bekommt eine ganz eigene Version dieser Variable mit ihrem ganz eigenen Speicherplatz. Da jede .c-Datei eine abgeschlossene Kompilationseinheit ist (d.h. der Compiler weiss nichts von gleichlautenden Variablen in anderen .c-Dateien), geht das solange gut, bis die erzeugten Object-Files gelinkt werden sollen. Dann sieht der Linker eine Variable "main_choices" in action_funcs.o, eine in set_funcs.o usw. Wegen dieses Namenskonfliktes geht das Linken dann in die Hose.

Du musst also im Header-File aus den Definitionen Deklarationen machen: Aus
Code:
static struct part_table
{

      char swap[30];
      char root[30];
      char fs[15];
}hdd_info;
musst Du ein
Code:
extern struct part_table
{

      char swap[30];
      char root[30];
      char fs[15];
}hdd_info;
machen. In irgendeiner passenden .c-Datei gehört dann natürlich noch die Definition der Variablen hinein:
Code:
struct part_table hdd_info
Mache diese Variable aber nicht static! Damit würdest Du die Variable privat für die .c-Datei definieren und die anderen Objectfiles bekämen diese nicht zu sehen und könnten dann ihre Verweise auf die Variable beim Linken nicht aufgelöst bekommen.


Jochen
_________________
Die grösste Lüge der EDV? "Mal eben..."
 
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen

blubb
Gast





BeitragVerfasst am: 25. Nov 2004 18:36   Titel:

super, danke, endlich erscheint mir das alles logischer Wink
werds gleich mal probieren

big thx

blubb
 

blubb
Gast





BeitragVerfasst am: 25. Nov 2004 18:41   Titel:

eine frage noch; wie soll ich das dann mit den ganzen strings machen?

zb.:
Code:

char *main_choices[] =
{
   "1) Keymap",
     "2) Swap partition",
     "3) Root partition",
     "4) FS Type",
     "5) Install",
     "6) Config",
     "7) Exit",
};

soll ich einfach ein extern vor das char schreiben? weil das ist ja eine definition, oder gibts so probs...?
 

blubb
Gast





BeitragVerfasst am: 26. Nov 2004 13:18   Titel:

das ist jetzt etwas bloed weil ich die definition in mehreren c files brauche, und somit bin ich wieder beim alten problem... da muesste ich alles neu schreiben...
werd wohl einfach alles in eine datei packen, beim naechsten mal weis ichs...

blubb
 

_MP_



Anmeldungsdatum: 04.09.2004
Beiträge: 45

BeitragVerfasst am: 26. Nov 2004 14:19   Titel:

blubb hat folgendes geschrieben::
soll ich einfach ein extern vor das char schreiben


Jepp, genau so. Wobei man globale Variablen aber eigentlich vermeiden sollte. Vielleicht wäre es besser, wenn du dein Programm ein wenig umstrukturierst? Für mich sieht das aus, als ob eine separate drawMenu()-Funktion für dich genau das richtige ist, in der dann dieses Menü aus deinem char-Array gezeichnet/ausgegeben wird.
_________________
cu

MP

http://www.linuxboard.org - das Linux Entwickler- und Anwenderforum
 
Benutzer-Profile anzeigen Private Nachricht senden

jochen
prolinux-forum-admin


Anmeldungsdatum: 14.01.2000
Beiträge: 699
Wohnort: Jülich

BeitragVerfasst am: 05. Dez 2004 12:21   Titel:

Hi,

ich war die letzte Zeit etwas netzfern und konnte daher nicht weiter posten. Ich hoffe, es ist noch nicht zu spät?...

Ich habe die Vorgehensweise mal in ein paar Dateien gepackt.

Code:
/* Datei a.h */
#ifndef A_H
#define A_H

struct gruss {
        char *hallo;
        char *welt;
};

extern struct gruss meingruss;

#endif
Hier ist die Deklaration der Struktur und einer globalen Variablen "meingruss". Da hier noch kein Speicher bereitgestellt wird, kann auch keine Initialisierung erfolgen!

Code:
/* Datei a.c */
#include "a.h"
#include "b.h"

struct gruss  meingruss = { "Hallo", "Welt" };

int main (void) {
        sei_freundlich();
        return 0;
}
Hier ist jetzt die Definition zu finden! Und da hier Speicherplatz bereitgestellt wird, kann auch die Initialisierung erfolgen.

Code:
/* Datei b.h */
#ifndef B_H
#define B_H

void sei_freundlich(void);

#endif
Damit a.c von der Funktion in b.c erfährt, muss der Prototyp der Funktion bekanntgemacht werden. Das geschieht in der Headerdatei. Jetzt der Source-Code:
Code:
/* Datei b.c */
#include <stdio.h>
#include "a.h"
#include "b.h"

void sei_freundlich(void) {
        printf ("%s %s\n",meingruss.hallo, meingruss.welt);
}
Hier wird auf die globale Variable meingruss zugefriffen. Aus a.h weiss die Funktion, dass es sie gibt und welchen Typ sie hat. Daher kann der Compiler die Datei übersetzen. Beim Linken wird der Verweis auf die in a.c definierte Variable gesetzt.

So, sind jetzt alle Klarheiten beseitigt? Wink Allerdings möchte ich mich _MP_ anschliessen: Dieser Aufbau ist nicht gerade elegant. Das Handeln eines Menus sollte sich sehr schön kapseln lassen, so dass Du nach Aufruf einer menu-Funktion nur definierte Rückgabewerte (in der .h-Datei als #defines gesetzte int-Konstanten) zu verarbeiten brauchst...

Jochen
_________________
Die grösste Lüge der EDV? "Mal eben..."
 
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen

Beiträge vom vorherigen Thema anzeigen:   
     Pro-Linux Foren-Übersicht -> Programmieren - C Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehen Sie zu:  

Powered by phpBB © phpBB Group
pro_linux Theme © 2004 by Mandaxy