www.mikrocontroller.net

Forum: PC-Programmierung Visual Studio Linker LNK2001 Problem


Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe mir eine kleine Win32Konsolen app gebastelt und möchte jetzt 
die funktionen in eine c datei auslagern, gesagt getan.

zu der *.c gibts auch eine *.h und das greift auch alles ineinander.

Doch leider habe ich seit dem "Umzug" diesen Fehler:

 error LNK2001: Nichtaufgeloestes externes Symbol "unsigned char __cdecl 
Date_Calc_MaxDay(struct date_t *)"

Links in der KLassenübersicht werden alle Funktionen aus der 
ausgelageterten *.c und *.h datei angezeigt, die funktionsprototypen 
sind alle vorhanden, und es kommt auch ein *.obj zustande. Die dateien 
leigen in Veruzeichnis des Hauptprogrammes...

Für mich sieht es so aus als würde er die funktionen beim linken nicht 
finden, die Frage ist nur, warum?

Ich bin am ende mit meinem Latein....

Habt Ihr einen Tip für mich!?

Danke,
Hannes

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das C-Source-File, in dem die Implementierung von Date_Calc_MaxDay zu 
finden ist, ist auch Bestandteil des Projektes? Das wird auch übersetzt?

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jap, ist in der Umgebung auch als datei mit zugefügt und es gibt auch 
das Date.obj. zu dem Date.c. Sogar die Funktionen aus der Datei werden 
alle im Objektbrowser mit aufgeführt...

Ich habe schon gedacht das es evtl. daran liegen kann das es kein cpp 
code ist, und es deswegen nicht zusammen spielt. Als es in der main.cpp 
war, ging es jedenfalls problemlos und da ich nicht der studio spezi 
bin...

Hannes

Autor: Sven Meier (smeier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hannes!

Ich hoffe ich bekomme das alles noch richtig zusammen...

Der Visual Studio Compiler ist ein C++-Compiler. Dies haben die 
Eigenheit, dass sie die Funktionsnamen noch um Angaben zur Klasse und 
den übergebenen Paramtern erweitern, bevor sie das Symbol im Objektfile 
ablegen. Der Compiler muss dies tun, um ein Überladen von Funktionen in 
C++ zu ermöglichen.
Wenn die Definition (in der Regel im c-File) und die Deklaration (in der 
Regel im h-File) sich in der Parameterliste unterscheiden, kann es dann 
dazu kommen, dass der Aufruf der Funktion eben minimal anders lautet, 
als das Symbol selbst. Das Resultat daraus ist, dass der Linker das 
Symbol nicht findet.

Um Linker und Compiler mitzuteilen, dass er C-Code und nicht C++-Code 
aufrufen soll und damit die Benamungen richtig zu machen muss im .h-File 
bei der Deklaration der Funktion ggfs. auch ein

extern "C" {
  Deklaration der C-Funktionen
}

eingefügt werden.

VG,
Sven

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es kann auch einfach daran liegen, daß ein Teil der Quelltexte
auf .c endet, ein anderer auf .cpp.

In den *.cpp wird dann das "name mangling" gemacht, also die
Signatur in den Namen einkodiert, in den *.c nicht.
(Auch der Visual-C++ macht das nur für C++, nicht für C.)
Dann stimmen die Namen die der Linker sieht nicht überein und Pech.

Lösung: Entweder alles in .c (keine .cpp) oder alles in .cpp (und
keine .c), oder in den Headerdateien etwas ändern:
#ifndef  __meinetolle_h_
#define __meinetolle_h_

#ifdef __cplusplus
extern "C"
{
#endif

// hier alles, was so deklariert werden soll...
// ...


#ifdef __cplusplus
}
#endif

#endif /* ndef __meinetolle_h_ */

Dadurch wird das Mangling unterbunden, und die Headerdatei ist
sowohl für C als auch C++ geeignet.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sven,

bin gerade dabei, es muss daran liegen aber gelöst bekomme ich das noch 
nicht...
http://developers.sun.com/solaris/articles/mixing.html

extern "C"
{
void Date_Print(date_t* p_date);

uint8_t Date_Check_Date (date_t* p_date);

void Date_Calc_Week(date_t* p_date);

void Date_Calc_Calweek(date_t* p_date);

uint8_t Date_Calc_MaxDay(date_t* p_date);
}


führt zu:

error C2059: syntax error : 'string'

Danke für den Tip

Hannes

Spiel gerade hiermit:
#ifdef __cplusplus
extern "C"
#endif

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Klaus,

da bin ich auch gerade bei... jetzt habe ich mal dein Beispiel probiert:


#ifndef DATE_H
#define DATE_H

#ifdef __cplusplus
extern "C"
{
#endif


#include "inttypes.h"

#define DATE_MONTH      12

typedef struct
{
    uint32_t    day     : 5,
                month   : 4,
                year    :13,
                week    : 3,
                calweek : 6,
                leapjear: 1;
}date_t;

void Date_Print(date_t* p_date);

uint8_t Date_Check_Date (date_t* p_date);

void Date_Calc_Week(date_t* p_date);

void Date_Calc_Calweek(date_t* p_date);

uint8_t Date_Calc_MaxDay(date_t* p_date);

#ifdef __cplusplus
}
#endif



#endif

immer noch:

Hauptprg24.obj : error LNK2001: unresolved external symbol "void __cdecl 
Date_Print(struct date_t *)" (?Date_Print@@YAXPAUdate_t@@@Z)
Hauptprg24.obj : error LNK2001: unresolved external symbol "void __cdecl 
Date_Calc_Calweek(struct date_t *)" 
(?Date_Calc_Calweek@@YAXPAUdate_t@@@Z)
Hauptprg24.obj : error LNK2001: unresolved external symbol "void __cdecl 
Date_Calc_Week(struct date_t *)" (?Date_Calc_Week@@YAXPAUdate_t@@@Z)
Hauptprg24.obj : error LNK2001: unresolved external symbol "unsigned 
char __cdecl Date_Calc_MaxDay(struct date_t *)" 
(?Date_Calc_MaxDay@@YAEPAUdate_t@@@Z)
Hauptprg24.obj : error LNK2001: unresolved external symbol "unsigned 
char __cdecl Date_Check_Date(struct date_t *)" 
(?Date_Check_Date@@YAEPAUdate_t@@@Z)

au man, das ist aber auch deprimierend...

Hannes

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sind die Dateinamen der beteiligten Dateien.
Es reicht, wenn du die cpp und c aufführst.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die jetzt geposteten Fehlermeldungen widersprechen dem Verwenden mit 
'extern "C"', denn jetzt werden die durch das "name-mangling" erzeugten 
Symbolnamen ausgegeben.

Der Code, aus dem die Funktionen aufgerufen werden, der nutzt nicht die 
mit 'extern "C"' modifizierten Prototypen. Den Linkerfehlermeldungen 
nach müsste das die Datei "Hauptprg24.cpp" sein.

Könnte es sein, daß Du die Funktionsprototypen an mehreren Stellen 
deklariert hast?

Pack Dein gesamtes Projekt in ein Zip-Archiv und poste das hier, dann 
kann ich Dir morgen helfen.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen vielen Dank für die Tips, die Geschchte mit dem extern "C" hat 
doch geholfen. Ich war eben nochmal am Rechner, und das Projet nochmal 
neu gebaut, weil ich es anschließend zippen wollte und siehe da, es 
läuft, die Fehlermeldungen sind weg.

Compiling...
Date.c
Hauptprg24.cpp
Linking...

Hauptprg24.exe - 0 error(s), 0 warning(s)

Wie gesagt vielen Dank nochmal.

Gruß,
Hannes

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.