2010-08-18 17 views
12

Ich habe eine Bibliothek, die eine Inline-C-Funktion verwendet, und kompiliert gerade gut. Wenn eine andere Bibliothek diese Bibliothek referenziert, wird sie trotzdem kompiliert. Wenn jedoch eine tatsächliche Anwendung auf die Bibliothek verweist, kann sie nicht kompiliert werden, da das Symbol _functionNameHere (ja, Funktionsname, das mit Unterstrich beginnt) - nicht gefunden wird.Ziel C: Inline-Funktion - Symbol nicht gefunden

Wenn ich den Inline-Spezifizierer entferne, wird alles gut kompiliert. Solange eine Funktion innerhalb der Bibliothek eingebunden ist, kann die App nicht kompiliert werden!

Irgendwelche Ideen, warum das ist?

Ich weiß ziemlich viel über Compiler, aber ich bin neu im Objective-C, und alles, was ich darüber weiß, ist nichts weiter als fundierte Vermutungen. Und selbst auf diese Weise kann ich mir keinen Grund vorstellen, dass es sich so verhält.

Die Sache ist, die Inline-Funktion ist INLINE, was bedeutet, dass es kein Symbol gibt, es wird inline kompiliert, wo auch immer es heißt, und die referenzierende App sollte nicht einmal wissen, dass es jemals existiert hat. Das ist wahr, solange die Inline-Funktion immer Inline-fähig ist und für die Bibliothek privat ist, und es gibt keine spezielle Compiler-Konfiguration, die das Inlining verhindert, und all dies ist wahr.

So jemand bitte kommen und mit dem Finger auf, was ich tue/denken falsch ...

Danke :-)

Antwort

36

Sie die statischen Spezifizierer auf Ihre Inline-Funktionsdefinition sollte hinzufügen wenn die Funktion zur bestimmungsgemäßen Verwendung ist nur in derselben Übersetzungseinheit (interne Bindung),

static inline int add(int x, int y) {return x+y;} 
int s = add(1, 2); 

wenn Sie weglassen statische im Beispiel oben (in Debug Konfigu Wenn keine Optimierung durchgeführt wird und kein Inlining ausgeführt wird, wird der Linker mit Fehler beendet. _Add wird referenziert, aber Symbol (e) nicht gefunden.

In C99 generiert eine Inline-Funktionsdeklaration ohne Speicherspezifizierer keinen tatsächlich aufrufbaren Funktionskörper, sodass der Linker einen Fehler anzeigt, wenn er benötigt wird.

Wenn Ihre Inline-Funktion von anderen Modulen verwendet werden kann, ist es komplizierter. Eine gängige Praxis ist es, die Inline-Funktionsdefinition (ohne extern) in die Header-Datei aufzunehmen und genau eine Prototyp-Deklaration mit extern in genau einem Modul zu enthalten.

Ein guter Artikel erklärt, Inline-Funktionen in C99: http://www.drdobbs.com/184401540

+0

Arrix - ich testete nur auf das, was Sie hier erklärt. Wenn ich 'inline double radians (double degrees) hinzufüge {Rückgabegrade * M_PI/180; } 'an den Anfang einer ViewController.m-Datei rufen Sie dann radians() in einer Methode in dieser Datei, bekomme ich den Linker-Fehler, obwohl ich meine Konfiguration auf Release eingestellt habe. Sicher in diesem Fall ist die Funktion inline und so das statische Schlüsselwort ist nicht notwendig? – Brynjar

0

nur FOUNDATION_EXPORT hinzufügen auf dem Header funktionieren (.h). Merken Sie sich import Foundation/Foundation.h (OS X) oder UIKit/UIKit.h (ios).

Beispiel:

//.h 
#import <UIKit/UIKit.h> 

FOUNDATION_EXPORT inline NSString * myInlineFunction(void); 
Verwandte Themen