Link Error LNK2019
-
Ich könnte grad verzweifeln.
Also, wenn ich das extern "C" nur in der cpp-verwende, bekomme ich folgende Fehlermeldung:
c:\dld\pf_2d_mod\so\dld.cpp(114) : error C2732: Bindungsangaben widersprechen vorheriger Angabe für 'geth'
c:\dld\pf_2d_mod\so\dld.cpp(113): Siehe Deklaration von 'geth'
c:\dld\pf_2d_mod\so\dld.cpp(153) : error C2732: Bindungsangaben widersprechen vorheriger Angabe für 'get_dld_Mat'
c:\dld\pf_2d_mod\so\dld.cpp(152): Siehe Deklaration von 'get_dld_Mat'
c:\dld\pf_2d_mod\so\dld.cpp(239) : error C2732: Bindungsangaben widersprechen vorheriger Angabe für 'get_Qv_ind'
c:\dld\pf_2d_mod\so\dld.cpp(238): Siehe Deklaration von 'get_Qv_ind'Wenn ich es zusätzlich in der Header Datei verwende (ohne #ifdef):
c:\dld\pf_2d_mod\so\dld.h(5) : error C2059: Syntaxfehler: 'Zeichenfolge'
Wenn ich es zusätzlich in der Header Datei verwende (mit #ifdef):
Über 100 Fehlermeldungen. Einige Beispile:
c:\programme\microsoft visual studio 8\vc\include\new(53) : error C2732: Bindungsangaben widersprechen vorheriger Angabe für 'operator delete'
c:\programme\microsoft visual studio 8\vc\include\new(53): Siehe Deklaration von 'operator delete'c:\programme\microsoft visual studio 8\vc\include\iosfwd(39) : error C2894: Vorlagen können nicht mit 'C'-Bindung deklariert werden
c:\programme\microsoft visual studio 8\vc\include\iosfwd(601) : error C2733: Zweite C-Bindung für überladene Funktion 'std::_Traits_helper::copy_s' nicht zulässig
c:\programme\microsoft visual studio 8\vc\include\iosfwd(597): Siehe Deklaration von 'std::_Traits_helper::copy_s'
-
- Mach nur einen Thread zum gleichen Thema im Forum auf
- Versuche nicht C und C++ in einem Header zu mixen und dann von c- und c++ dateien darauf zuzugreifen. (Die c-Datei wird Panik schieben)
- Versuche nicht extern "C" class xxxx {};
- Versuche nicht extern "C" template...
- Versuche nicht extern "C" vector<...>
-
Punkt 1: Verstanden werde ich. Bin nur etwas verzweifelt sorry

Punkt 3-5: Habe keine solchen Deklarationen.
Punkt 2: Ich dachte wenn ich die Funktionsdeklaration in eine Headerdatei schreibe, muss ich dies header-datei dann auch im souce-file mit den zugehörigen Funktionsdefinitionen "includieren". Scheint nicht der Fall zu sei. wenn ich das #include "../so/dld.h" aus der dld.cpp Datei entferne, funktioniert es.
Vielen Dank, wüsste nicht was ich ohne eure Hilfe machen würde.
-
Habe deinen Source Code mal in ein Projekt gepackt, Returnwerte in
die Funktionen geschrieben und kompiliert.
In meiner main Funktion habe ich deine Funktionen auch aufgerufen.
Klappt.Muß also an deinen Projektsettings bzw. an deinen Include Pfaden liegen.
-
Um es nochmal zusammenzufassen:
Wenn Du in einem C-File einen Header einbindest, der zu einer C-Bibliothek gehört, musst Du nichts unternehmen. extern "C" kennt der C-Compiler nicht.
Wenn Du in einem C++-File einen Header einbindest, der zu einer C-Bibliothek gehört, müssen die Deklarationen mit extern "C" { ... } umschlossen werden. Damit sowohl ein C- als auch ein C++-Compiler denselben Header verstehen können, kannst Du die Einleitung sowie die schließende Klammer jeweils durch #ifdef abgrenzen. Klar sollte sein, dass nur Deklarationen, die C überhaupt versteht, so exportiert werden können. D.h. keine Klassen, keine Templates, keine Operatoren, keine Überladung.
Wenn Du ein C-File übersetzt, welches Du in einem C++-File benutzen möchtest, musst Du nichts unternehmen, wenn der Header bereits stimmt.
Wenn Du ein C++-File übersetzt, welches Du in einem C-File benutzen möchtest, müssen alle Definitionen der Funktionen, welche im Header bereits extern "C" markiert sind, nochmal durch dieses umschlossen werden.
Für Dich treffen die Punkte zwei und vier zu, weitere Fehler können nur der Klammerung zu verdanken sein. (Achte darauf, dass die schließende Klammer von extern "C" vor irgendwelchen C++-Definitionen kommt).
-
so hab ichs jetzt auch gmeacht. nur mache ich jetzt in dld.cpp kein #include "dld.h". dann gehts. sonst krieg ich fehler.
-
ich habe in der CPP Datei ein #include "dld.h" drin
Linkerfehler sind immer dann, wenn der Kompilier die Deklaration findet, aber die Implementierung nicht.
Außderdem hast du normale Funktionen, die du in C als auch in C++ Klassen verwenden kannst auch ohne extern "C" und das ganze Geraffel.
Der C++ Kompiler ist doch viel besser, weil er den Funktionsnamen und die Parameter beachtet. Durch extern "C" verklickerst du dem Kompiler nur, dass
er den Funktionsnamen beachten soll. Das ist doch an dieser Stelle völliger
Quatsch.Die gleichen Funktionen kannst du auch in eine Klasse stopfen, dann schon ehr nach C++ aus, obwohl dann noch eine Menge fehlt.
-
Diese extern "C" Sache kann ich im headerweglassen weglassen. Im cpp brauche ich das aber. Sobald ich jedoch #include "dld.h" in dld.cpp schreibe, bekomme ich die Linker-Fehler. Wenn ich es weglasse, scheint alles zu funktionieren. Anscheinend findet der Linker die Definition der Funktionen in dld.cpp, auch wenn da dld.h nicht "includiert" ist.
Naja,Hauptsache es läuft irgendwie.
Nochmal Dank an alle, dies sich zu diesem Thema geäussert haben.
-
schokomann schrieb:
Der C++ Kompiler ist doch viel besser, weil er den Funktionsnamen und die Parameter beachtet.
Eben. Und wenn der C-Compiler diese Funktion dann importieren soll, findet er sie nicht, weil er eben das nicht tut.
pitaz schrieb:
Diese extern "C" Sache kann ich weglassen.
An welcher Stelle?
Magst Du noch mal das komplette Projekt in seiner jetzigen (funktionierenden) Form posten?
EDIT2:
Achja, Du übersetzt schon das, was die Endung .cpp hat, mit einem C++-Compiler, und das, was die Endung .c hat, mit einem C-Compiler, ja?EDIT:
Beispielhaft sollte das so aussehen:// funktionen.h #ifdef __cplusplus extern "C" { #endif void funktion(int param); #ifdef __cplusplus } #endif // funktionen.cpp #include "funktionen.h" extern "C" { void funktion(int param) { } } // programm.c #include "funktionen.h" int main() { funktion(12); }
-
Er nimmt VS 2005 und seine Funktion hat nichts C specifisches was der C++ von VS 2005 nicht könnte. Also braucht er dieses extern "C" nicht.
Nur wenn man diese uralten C Funktionen deren schreibweise auch nicht anders
ist einbindet und einen C++ Kompiler verwendet, dann muss man das manchmal machen.
Sonst geht das auch ohne und das hat nichts mit den hier beschriebenen Linker Fehlern und den gezeigten Funktionen zu tun.
-
Also, das "gesamte" (jedenfalls Teile der 3 Files) nochmal:
dld.h:
#ifndef DLD_H #define DLD_H //#ifdef __cplusplus //extern "C" { //#endif int geth(double x, double t, double *h); int get_Qv_ind(double x, double r, double t, double T, double *Qv_ind); int get_dld_Mat(); //#ifdef __cpluspus //} //#endif #endifdld.cpp
//#include "../so/dld.h" #include "../hd/ge_types.h" #include <iostream> #include <vector> #include <string> #include <fstream> #include <cstdio> #include <cmath> using namespace std; const double pi = 3.14159265; // Pi //Private Variables vector< vector<double> > dld_Mat; // Matrix with Temperature and corresponding material properties // Mat[T][i] = ith property at Tm // i=0: Temperature (=T) [C] // i=1: thermal conductivity [W/(m*K)] // i=2: heat capacity [J/(kg*K)] // i=3: density [kg/m3] // i=4 resistivity [Ohm/m] fstream infile; string s; double dld_Mu0 = 4*pi*1.e-7; // magnetic constant [H/m] //Parameters of Heating/Cooling-Device double dld_hc_x0 = 0.2; //absolute start coordinate of left end of Heating/Cooling-Device [m] double dld_hc_v = 0.005; //velocity of cooling device [m/s] //Noch mehr solche Variablen werden initialisiert und definiert. //Wird in den anderen 3 Funktionen benötigt double evalfx(double x_coil, double l_coil, double r_coil, double x) { return 1/(2*l_coil) * ((x_coil+l_coil-x)/sqrt(pow(x_coil+l_coil-x,2) + pow(r_coil,2)) - (x_coil-x)/sqrt(pow(x_coil-x,2)+pow(r_coil,2))); } //Wird in den anderen 3 Funktionen benötigt double evalh(double a1, double a2, double xc, double b, double x) { return (a2-a1)/pi*atan(b*(x-xc))+(a2-a1)/2+a1; } extern "C"{ int geth(double x, double t, double *h) { //Funktiondefinition } int get_dld_Mat() { //Funktionsdefinition } int get_Qv_ind(double x, double r, double t, double T, double *Qv_ind) { //Funktionsdefinition } }so_temp.c:
#include <stdio.h> #include <math.h> #include "../hd/ge_types.h" #include "../hd/pa_parallel.h" #include "../hd/so_routines.h" #include "../hd/me_interface.h" #include "../hd/el_variables.h" #include "../hd/me_variables.h" #include "../hd/ma_variables.h" #include "../hd/nl_variables.h" #include "../hd/co_variables.h" #include "../so/dld.h" static int so_nTrias, so_nQuads, so_nElems, so_nNQuads, so_nCQuads, so_nNodes; //Auch hier werden zusätzlich noch einige Variablen deklariert static int tl_so_ThermoSolve ( VOID ); static int tl_so_HeatSurfaceFluid int nNodes, double pNodalArea[], int Mat[], double Temp[], double time, double Q[] ); //Deklaration weitere Funktionen (in C) //Definition der Funktionen //geth, get_dld_Mat und get_Qv_ind werden nun in den Funktionen tl_so_ThermoSolve und tl_so_HeatSurfaceFluid aufgerufenWenn ich das extern "C" in dld.cpp weglasse, kriege ich wieder die Linker-Fehler
-
schokomann schrieb:
Er nimmt VS 2005 und seine Funktion hat nichts C specifisches was der C++ von VS 2005 nicht könnte. Also braucht er dieses extern "C" nicht.
Das stimmt nicht, weil eben, wie Du bereits zutreffend festgestellt hast, der C++-Compiler die Funktionssignaturen beachtet, und ein C-Compiler nicht. Ein C++-Compiler erzeugt also Funktionen unter Beachtung der Signatur, aber der C-Compiler, der diese Objekte benutzen soll, sucht die Funktionen ohne die Signatur zu beachten. Extern "C" braucht man auch nicht manchmal wenn der Compiler Lust drauf hat, sondern zu fest definierten Zwecken, von denen der hier (nicht nur manchmal) einer ist.
Beispiel:
Ein C++-Compiler übersetzt die Funktion "void function(int param)" und nennt sie, weil er die Signatur beachtet, im Objekt "function_i4". Ein C-Compiler übersetzt ein Programm, welches die Funktion deklariert, und sucht sie, weil er die Signatur nicht beachtet, unter dem Namen "function". Der Linker fügt nun beide Objekte zusammen und stellt fest, dass es "function" nicht gibt.LordJaxom schrieb:
Für Dich treffen die Punkte zwei und vier zu, weitere Fehler können nur der Klammerung zu verdanken sein.
Wie ich bereits vermutet hatte, in der H-Datei fehlt die schließende Klammer von extern "C", weil Du __cpluspus abfragst, statt __cplusplus.
-
Oje, das geht auf meine Kappe, den exakten Typo habe ich leider drüben im MFC-Forum gemacht

-
sollte ich denn auch ein #include "dld.h" in dld.cpp haben? Funktioniert jedenfalls ohne.
Danke für den Hinweis, jetzt funktionierts auch wenn ich #include "dld.h" drinlasse.