Ich erhalte immer einen Build-Fehler, wenn ich versuche, eine C-Funktion in der Header-Datei direkt über der Schnittstelle der Klasse zu definieren.
aber wenn ich das gleiche in der Implementierungsdatei mache und eine Deklaration in der Kopfzeile gebe. Die Dinge funktionieren.
Ich wollte wissen, warum es so ist, weil ich enums, structs, konstante NSStrings in der Header-Datei definiert habe, also warum funktioniert C nicht?
Dies hat damit zu tun, wie der C-Linker (oder Link-Editor) funktioniert. Wenn der C-Compiler auf eine Funktionsdefinition stößt, bereitet er den Assembler-Code vor, der diese Funktion implementiert, und markiert ihn mit einem -Symbol , das zum Linker sagt: "Hier beginnt die Funktion mit diesem Namen". Das Symbol wird normalerweise mit einem Unterstrich gefolgt von dem Funktionsnamen, z.B. _printf
.
Wenn Sie die Funktion in einer Headerdatei definieren, kompiliert jede .c
oder .m
-Datei, die diesen Header importiert, die Funktion und bewirkt, dass der Compiler dasselbe Symbol ausgibt. Der Linker erwartet, nur eine Instanz jedes Symbols zu finden, also ist dies ein Fehler.
Dies hängt nicht mit der Existenz von #include
guards oder der Verwendung von #import
anstelle von #include
zusammen. Der C-Compiler arbeitet an einzelnen Übersetzungseinheiten - womit er einzelne Quelldateien meint. Präprozessor-Strategien verhindern, dass Sie dieselbe Header-Datei zweimal in eine einzelne Quelldatei aufnehmen, aber nichts tun, um Aktivitäten über mehrere Dateien hinweg zu koordinieren. Das bedeutet, dass es zulässig ist, die gleichen Header in verschiedene Quelldateien einzufügen. Das bedeutet auch, dass sie beim Kompilieren verschiedener Dateien (legal) das gleiche Symbol enthalten können.
Es ist die Aufgabe des Linkeditors, diese Dateien zusammenzufassen und alle Verweise auf Symbole aufzulösen, die zum Zeitpunkt der Kompilierung unbekannt waren. Wenn Sie versuchen, Objekte (den Namen von kompilierten und assemblierten Übersetzungseinheiten) mit demselben Symbol in dasselbe Archiv, dieselbe Bibliothek oder dieselbe ausführbare Datei zu verknüpfen, erhalten Sie den Fehler, den Sie hier sehen.
Lösungen:
inline
. Inline-Funktionen werden vom Compiler nur in die Funktion kopiert, in der sie aufgerufen werden. Daher wird für sie kein Linkersymbol ausgegeben. Dies hat seine eigenen Kompromisse, die Sie lesen möchten mehr über . Tags und Links objective-c