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
Das C-Source-File, in dem die Implementierung von Date_Calc_MaxDay zu finden ist, ist auch Bestandteil des Projektes? Das wird auch übersetzt?
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
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
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.
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
@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
Wie sind die Dateinamen der beteiligten Dateien. Es reicht, wenn du die cpp und c aufführst.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.