2010-08-18 2 views
12

J'ai une bibliothèque qui utilise une fonction en ligne C, et compile très bien. Lorsqu'une autre bibliothèque fait référence à cette bibliothèque, elle est toujours compilée correctement. Mais si une application réelle fait référence à la bibliothèque, elle ne parvient pas à se compiler, indiquant que le symbole _functionNameHere (oui, nom de la fonction commençant par souligné) - symbol est introuvable.Objectif C: fonction inline - symbole non trouvé

Si je supprime le spécificateur en ligne, tout compile bien. Mais tant qu'une fonction est en ligne dans la bibliothèque, l'application ne peut pas compiler!

Des idées pour expliquer pourquoi?

Je connais à peu près les compilateurs, mais je suis nouveau dans l'Objective-C, et tout ce que je sais à ce sujet n'est rien de plus que des suppositions éclairées. Et même de cette façon, je ne peux pas penser à une raison pour laquelle il se comportera de cette façon. Le fait est que la fonction inline est INLINE, ce qui signifie qu'il n'y a pas de symbole du tout, qu'elle est compilée inline partout où elle est appelée, et que l'application de référencement ne devrait même pas savoir qu'elle existait. Cela est vrai tant que la fonction inline est toujours inline-able, et est privée à la bibliothèque, et il n'y a pas de configuration spéciale du compilateur qui empêche l'inlining, et tout cela est vrai.

Donc, tout le monde s'il vous plaît venez pointer du doigt ce que je fais/penser mal ...

Merci :-)

Répondre

36

Vous devez ajouter le statique spécificateur à votre définition de la fonction en ligne si la fonction est destinée à être utilisée uniquement dans la même unité de traduction (liaison interne),

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

Si vous omettez statique dans l'exemple ci-dessus (en Debug CONFIGUR ation, où aucune optimisation n'est effectuée et aucun inlining n'est effectué), l'éditeur de liens quittera avec une erreur se plaignant _add est référencé mais Symbol (s) pas trouvé.

Dans C99, une déclaration de fonction inline sans spécificateur de stockage ne génère pas de corps de fonction réellement appelable, de sorte que l'éditeur de liens donne une erreur lorsqu'il en a besoin.

Si votre fonction inline peut être utilisée par d'autres modules, c'est plus compliqué. Une pratique courante consiste à inclure la définition de la fonction inline (sans extern) dans le fichier d'en-tête et à inclure exactement exactement une déclaration prototype avec extern dans exactement un module.

Un bon article expliquant les fonctions inline dans C99: juste http://www.drdobbs.com/184401540

+0

Arrix - Je viens de tester en fonction de ce que vous nous avez expliqué ici. Si j'ajoute 'double radians en ligne (doubles degrés) {return degrees * M_PI/180; } 'en haut d'un fichier ViewController.m puis appel radians() dans une méthode dans ce fichier, j'obtiens l'erreur de l'éditeur de liens, même si j'ai défini ma configuration sur Release. Sûrement dans ce cas, la fonction s/être en ligne et donc le mot-clé statique n'est pas nécessaire? – Brynjar

0

ajouter FOUNDATION_EXPORT à fonctionner sur l'en-tête (.h). N'oubliez pas d'importer Foundation/Foundation.h (OS X) ou UIKit/UIKit.h (ios).

Exemple:

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

FOUNDATION_EXPORT inline NSString * myInlineFunction(void); 
Questions connexes