Verlinkungsproblem header

Gast #4086028
Lesenswert?
• ▲
▼
Hallo Forum,


es geht bei mir um einen Verlinkungsfehler.

Ich habe im c-file (demmel.c) Funktionen geschrieben, die Funktionen aus 
einer anderen Header nehmen sollen.

Wenn ich in der c-Datei
1
#include <communication/I2C/TWI_Master/TWI_Master.h>

 einfüge, funktioniert es.

Die TWI_Master.h ist in dem Atmel Ordner vorhanden, sodass es mit "<>" 
klappt eigene Header Dateien einzubinden.

Ich habe jedoch eine weitere Header-Datei (demmel.h).
Wenn ich dort den include Befehl schreibe, dann gibt es den Fehler.

"Error  18  ld returned 1 exit status  collect2.exe  0  0  main".

In demmel.c ist auch "demmel.h" enthalten


Vielen Dank

Pete

P.S.

Sonst hat es immer so geklappt.
Gast #4086030
Lesenswert?
• ▲
▼
so klappts nicht:

demmel.h:
1
#include <communication/I2C/TWI_Master/TWI_Master.h> // enthällt #include <avr/io.h>
2

3

4
uint8_t demmel_send_i2c_instruction(uint8_t demmel_address, uint8_t instruction);
5

6
uint8_t demmel_i2c_read_data_size(uint8_t demmel_address);
7

8
uint16_t demmel_i2c_read_info(uint8_t demmel_address);

demmel.c:
1
#include "demmel.h"
2

3

4
uint8_t demmel_send_i2c_instruction(uint8_t demmel_address, uint8_t instruction)
5
{
6

7
  if ( !TWI_M_start(demmel_address, WRITE, NO_OPTION) )
8
  {
9
    
10
    demmel_i2c_stop();
11
    return NO_SUCCESS;
12

13
  }
14
  // Output command CC_DATA_SIZE_READ
15
  if ( !TWI_M_write(instruction) )
16
  {
17
    
18
    demmel_i2c_stop();
19
    return SUCCESS;
20
    
21
  }
22
  
23
  return SUCCESS;
24
  
25
}
Gast #4086034
Lesenswert?
• ▲
▼
so aber schon:

demmel.h:
1
#include <avr/io.h>
2

3

4
uint8_t demmel_send_i2c_instruction(uint8_t demmel_address, uint8_t instruction);
5

6
uint8_t demmel_i2c_read_data_size(uint8_t demmel_address);
7

8
uint16_t demmel_i2c_read_info(uint8_t demmel_address);


demmel.c:
1
#include "demmel.h"
2

3
#include <communication/I2C/TWI_Master/TWI_Master.h>
4

5
uint8_t demmel_send_i2c_instruction(uint8_t demmel_address, uint8_t instruction)
6
{
7

8
  if ( !TWI_M_start(demmel_address, WRITE, NO_OPTION) )
9
  {
10
    
11
    demmel_i2c_stop();
12
    return NO_SUCCESS;
13

14
  }
15
  // Output command CC_DATA_SIZE_READ
16
  if ( !TWI_M_write(instruction) )
17
  {
18
    
19
    demmel_i2c_stop();
20
    return SUCCESS;
21
    
22
  }
23
  
24
  return SUCCESS;
25
  
26
}



sind jetzt auch nur codeabschnitte. und das compilieren klappt so.
Gast #4086237
Lesenswert?
• ▲
▼
Ich hab hier nochmal die Kopie:

Error  1  multiple definition of `TWI_M_init'  c:\program files 
(x86)\atmel\atmel toolchain\avr8 
gcc\native\3.4.1056\avr8-gnu-toolchain\avr\include\communication\i2c\twi 
_master/twi_master.h   102  1  main
Gast #4086297
Lesenswert?
• ▲
▼
Mag sein, es handelt sich um ein Mißverständnis. Das räume doch bitte 
einmal aus.

Ein "Include-Guard" besteht nicht nur darin ein #define davon abhängig 
zu machen, ob es schon existiert. Es muss auch das #include Statement 
selbst davon abhängig sein. Dein Code zeigt leider weder das eine noch 
das andere und Deine Antwort von 12:49 eben nur das #define.

Bei komplexen Projekten kann man sich schon mal in einem Wust von 
geplant strukturierter Dateiorganisation, includes und make Anweisungen 
verstricken. Das ist allen schon mal passiert. Aber fang doch bitte 
damit an, einfach mal die Fehlermeldung zu posten. Am besten sogar 
mehrere (falls das zutrifft). Vielleicht die ersten 5 oder so. Nicht 
uninteressant wäre auch die Ausgabe des Build-Prozesses. Am besten als 
Anhang, weil die vermutlich recht lang ausfällt.
#4086316
Lesenswert?
• ▲
▼
pete schrieb:
> Ich hab hier nochmal die Kopie:
>
> Error  1  multiple definition of `TWI_M_init'  c:\program files
> (x86)\atmel\atmel toolchain\avr8
> gcc\native\3.4.1056\avr8-gnu-toolchain\avr\include\communication\i2c\twi 
_master/twi_master.h
> 102  1  main

Das ist aber ein ganz anderes Problem.
Du hast ein Header File und in diesem Header File ist der Source Code 
für die Funktion TWI_M_init drinnen.

Und genau das macht man nicht.
Im Header File steht nur der Funktionsprotoyp! Die Implementierung kommt 
in ein C-File und dieses C-File wird zum Projekt hinzugefügt, damit es 
mitcompiliert und mitgelinkt wird.

twi_master.h
1
#ifndef TWI_MASTER_INCLUDED
2
#define TWI_MASTER_INCLUDED
3

4
void TWI_M_init( void );
5
... alle anderen Funktionen als Protoyp
6

7
#endif

twi_master.c
1
#include <avr/io.h>
2
#include "twi_master.h>
3

4
void TWI_M_init()
5
{
6
  .... hier der Code
7
}
8

9
... und ditto für alle anderen Funktionen
Gast #4086319
Lesenswert?
• ▲
▼
Ups. Eine Fehlermeldung steht da ja schon. Sorry.

Was Du da hast, ist eine mehrfache Definition. D.h. in einem oder 
mehrere C-Files steht mindestens zweimal eine Funktionsdefinition. Ein 
Text, der eine Funktion zusammen mit dem Funktionsrumpf enthält. Alles 
andere ist eine Funktionsdeklaration, die dazu dient, dem Compiler 
Parameter und Rückgabewert einer später noch zu definierenden Funktion 
bekannt zu machen.

Die einfachste Methode, die ich verwende, ist eine Suche nach dem 
Funktionsnamen in allen Dateien. Das findet auch Deklarationen die man 
dem Augenschein nach noch von den Definitionen unterscheiden muss.

Viele IDEs bieten auch die Möglichkeit nach Definitionen zu suchen und 
lassen sich auch nicht von mehrfachen Definitionen abschrecken. 
Hilfreich finde ich auch Programme wie "sourcenav".
Gast #4086389
Lesenswert?
• ▲
▼
naja, ich mach das auch immer so, die Funktionsköpfe in die Header und 
den Code ins c-file.

Jedoch wenn man es mit "<>" Klammern einbinden möchte und nicht immer 
die Dateien in den Ordner mitreinzukopieren und in den Explorer 
einzufügen, müssen es Header mit den Code sein.


Komischerweißse hat es immer so funktioniert, jetzt plötzlich nicht mehr
#4086398
Lesenswert?
• ▲
▼
pete schrieb:
> naja, ich mach das auch immer so, die Funktionsköpfe in die Header und
> den Code ins c-file.
>
> Jedoch wenn man es mit "<>" Klammern einbinden möchte und nicht immer
> die Dateien in den Ordner mitreinzukopieren und in den Explorer
> einzufügen,

reinkopieren musst du nichts.
Jede einigermassen vernünftige IDE hat kein Problem damit, wenn die 
Source Code Files auf mehreren Verzeichnissen 'verteilt' sind.

>  müssen es Header mit den Code sein.

du siehst ja, was dann dabei rauskommt.
Header im Code funktioniert im Einzelfall, wenn dein Projekt aus 
lediglich EINEM C-File besteht. Sobald du aber dein Projekt auf mehrere 
C-Files aufteilst und einige davon inkludieren denselben Header, dann 
kracht es eben.

Fazit: Wenn man es richtig macht, funktioniert es immer. Wenn man 
Krücken akzeptiert, darf man sich nicht wundern, wenn man auch mal auf 
die Schnauze fällt.

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