Problem mit selbstgemachter header datei

OP #705776
Lesenswert?

Also, im Anhang mal das Programm.
Ich würde gerne hingehen und den ganzen krams, bis auf die 
Hauptfunktion, in eine .h datei auslagern.
Sowas habe ich bisher noch nie gemacht und mit einem einfachen billigen 
printf befehle, ausgelagert in einer Funktion, die wiederrum in einer .h 
datei steht, klappt das einwandfrei.


Mein Sourcecode läuft ebenfalls einwandfrei, allerdings lässt er sich 
nicht auslagern.

Ich habe einfach alles, bis auf Programm hauptteil in eine .h datei 
gepackt.
Natürlich oben schön include "displayinit.h".

Dann zeigt mir der Compiler aber in allen funktionsaufrufen beim 
compilieren das an: ERROR 104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: 
delay(DISPLAYINIT)


Woran liegt es und wo mache ich da den fehler?
Angehängte Dateien:
#705794
Lesenswert?

Vielleicht wäre es sinnvoll, Deinen Header-Versuch auch mal zu posten. 
Ich vermute aber stark, dass Du da was falsch verstanden hast: In eine 
Header-Datei werden keine Funktionen an sich ausgelagert. Die 
Header-Datei enthält ausschließlich Variablen- und 
Funktions-(Prototypen) Deklarationen. Die eigentlichen Funktionen kommen 
in eine .c-Datei, die separat kompiliert wird. Und drauf achten, dass in 
der Header-Datei "extern"-Deklarationen verwendet werden.
#705796
Lesenswert?

Beispiel anhand der Funktion timer_init:
Es gibt drei Dateien: "main.c", "functions.h" und "functions.c".

In "functions.c" steht
1
void timer_init(void)  
2
{
3
  // Timer 0 initialisieren
4
  TMOD = 0x01;          // 0000 0001B    Timer 0: Mode 1 (16-Bit Z�hler)
5
  TH0  =  0xAF;      //Ultra short couting time
6
  TL0  =  0xFF;    
7

8
  // Interruptsystem
9
  ET0  = 1;             // Timer 0, Interruptfreigabe
10
  EA   = 1;             // generelle Interruptfreigabe
11
}

In "functions.h" steht
1
extern void timer_init(void);

In main.c:
1
#include "functions.c"
2
//[...]
3
timer_init();
4
//[...]

main.c und functions.c werden dem Compiler bekanntgegeben (bei einer IDE 
dem Projekt hinzugefügt).
OP #705971
Lesenswert?

Das ist die test.c

#include "functions.c"
#include <reg51.h>
#include "displayinit.h"
sfr leds=0x80; //Hier ist die led low activ verschaltet.
sbit  DB4=0xB0;// Die Bezeichnungen der Ports des Displays
sbit  DB5=0xB1;//1 zu 1 verkabel wie der Name, also DB5 an D5
sbit  DB6=0xB2;
sbit  DB7=0xB3;
sbit  RS=0xB4;
sbit   EN=0xB5;
sfr port_B0=0xB0;
void main (void)
{
char display_ausgabe[12];
int i=0,length=12;
timer_init(); //Zuerst timer initialisieren!
display_init(); //Display init ausführen!
clear_display();
strcpy(display_ausgabe, "Hello World!");//SPEICHERRAUBEND und schreibt 
müll in leere Zeichen bei length 20
do{
put_to_lcd(display_ausgabe[i]);
i++;
}
while (i<length);
while(1);
{
}
}
OP #705972
Lesenswert?

Das ist die functions.h

#ifndef _FUNCTIONS_H
#define _FUNCTIONS_H
void delay(unsigned int delay_multi);
 void enable_routine(void)  ;
 void turnoff_display(void);
 void turnon_display(void);
 void clear_display(void);
 void timer_init(void);
 void display_init (void);
 second_byte(char uebergabewert);
 put_to_lcd (char uebergabewert);
#endif
#705973
Lesenswert?

Aaalso:

> Das ist die test.c

#include "functions.c"

macht man üblicherweise nicht, geht aber. Normalerweise wird das beides 
getrennt kompiliert (.o) und dann erst zusammengelinkt. Geht aber auch 
so.

> Type error in second_byte redeclaration
und put_to_lcd redeclaration.

Guck mal in die functions.c welchen Rückgabetyp du den beiden funktionen 
dort gegeben hast. Der muss mit dem in der functions.h übereinstimmen.
#706124
Lesenswert?

Also mal langsam, kein Rückgabewert bedeutet "void" (das ist dann der 
Rückgabetyp) und dann schreibst du in den Code "return;" ohne irgend'nen 
Wert. Funktionen ohne Angabe vom Rückgabetyp gibt es nämlich nicht, das 
läuft dann zwangsläufig auf einen Fehler hinaus.
Und "return 0;" könnte alles mögliche sein. Poste doch mal die 
functions.c, die fehlt.

Vielleicht solltest du dich erstmal ein bisschen mit C beschäftigen, das 
gehört schon zu den grundlegendsten Grundlagen.
#706738
Lesenswert?

I_ H. wrote:
> Also mal langsam, kein Rückgabewert bedeutet "void" (das ist dann der
> Rückgabetyp)

Fast.
Kein angegebener Rückgabetyp bedeutet 'int'

@Oliver
Es ist aber trotzdem besser, man nutzt dieses 'Feature' nicht aus,
sondern gewöhnt sich gleich guten Stil an:

Wenn eine Funktion einen int retourniert, dann lautet das

int foo()
{
   return 0;
}

Wenn eine Funktion keinen Rückgabewert hat, dann lautet das

void foo()
{
  // eventuell ein mglw. vorzeitiger return;
}


Lass den Compiler sowenig Annahmen wie möglich treffen.
#706760
Lesenswert?

Oliver D. wrote:
> Ich habe mir den wiki artikel durchgelesen und danach gearbeitet.

Der Artikel ist nicht besonders gut, weil er eigentlic aus
einer Anfrage, bei der es um 'extern' gegangen ist stammt.

Hat es denn trotzdem funktioniert?

>
> In meinem C buch steht übrigens garnichts zu header datein!

In deinem C-Buch stehen wahrscheinlich noch viele anderen
Praxistips zu C nicht drinnen :-)

Ich versuch mal eine Wette:
Ich wette, dass in deinem Buch eine Fahrenheit / Celsius umrechnung
drinnen ist und in dieser Umrechnung der Datentyp float vorkommt,
während double da drinn überhaupt nicht vorkommt. Generell
kann man sagen, dass im Buch als Standard-Gleitkommatyp meistens
float verwendet wird.

(Die Chancen für ein gewinnen der Wette stehen bei ca. 60%)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren