Forum: PC-Programmierung Visual Studio Linker LNK2001 Problem


von Hannes (Gast)


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

von Rufus Τ. F. (rufus) Benutzerseite


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?

von Hannes (Gast)


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

von Sven M. (smeier)


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

von Klaus W. (mfgkw)


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:
1
#ifndef  __meinetolle_h_
2
#define __meinetolle_h_
3
4
#ifdef __cplusplus
5
extern "C"
6
{
7
#endif
8
9
// hier alles, was so deklariert werden soll...
10
// ...
11
12
13
#ifdef __cplusplus
14
}
15
#endif
16
17
#endif /* ndef __meinetolle_h_ */

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

von Hannes (Gast)


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

von Hannes (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Hannes (Gast)


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

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.