2010-08-18 20 views
12

Tengo una biblioteca que utiliza una función C en línea, y está compilando muy bien. Cuando otra biblioteca hace referencia a esa biblioteca, todavía compila bien. Pero si una aplicación real hace referencia a la biblioteca, no compila, diciendo que el _functionNameHere (sí, nombre de la función que comienza con el subrayado) - no se encuentra el símbolo.Objetivo C: Función en línea - Símbolo no encontrado

Si elimino el especificador en línea, todo compila bien. ¡Pero mientras una función esté en línea dentro de la biblioteca, la aplicación no puede compilar!

¿Alguna idea de por qué es eso?

Sé casi todo sobre los compiladores, pero soy nuevo en el Objective-C, y todo lo que sé sobre él no es más que conjeturas. E incluso así, no puedo pensar en una razón por la que se comporte de esa manera.

El hecho es que la función en línea es INLINE, lo que significa que no tiene ningún símbolo, se compila en línea donde sea que se llame, y la aplicación de referencia ni siquiera debería saber que existió alguna vez. Esto es cierto siempre que la función en línea siempre esté en línea, y sea privada para la biblioteca, y no haya una configuración especial del compilador que impida la alineación y todas sean verdaderas.

Así, alguien por favor ven y apunta con el dedo a lo que estoy haciendo/pensando mal ...

Gracias :-)

Respuesta

36

debe agregar el especificador estática a su definición de función en línea si la función es para uso exclusivo en la misma unidad de traducción (enlace interno),

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

Si omite estática en el ejemplo anterior (en la depuración configur ación, donde no se realiza ninguna optimización y no se lleva a cabo la alineación), el enlazador saldrá con error al quejarse, se hace referencia aadd pero no se encuentran los símbolos.

En C99, una declaración de función en línea sin ningún especificador de almacenamiento no generará un cuerpo de función invocable real, por lo que el enlazador produce un error cuando lo necesita.

Si su función en línea puede ser utilizada por otros módulos, es más complicado. Una práctica común es incluir la definición de función en línea (sin extern) en el archivo de encabezado e incluir exactamente una declaración de prototipo con extern en exactamente un módulo.

Un buen artículo que explica las funciones en línea en C99: http://www.drdobbs.com/184401540

+0

Arrix - Sólo estaba probando en base a lo que se explica aquí. Si agrego 'doble radianes en línea (grados dobles) {grados de retorno * M_PI/180; } 'al principio de un archivo ViewController.m y luego llame a radianes() en un método en ese archivo, obtengo el error del enlazador, aunque configuré mi configuración como Release. Seguramente en este caso, la función s/be inlined y entonces la palabra clave static no es necesaria? – Brynjar

0

sólo tiene que añadir FOUNDATION_EXPORT para funcionar en la cabecera (.h). Recuerde importar Foundation/Foundation.h (OS X) o UIKit/UIKit.h (ios).

Ejemplo:

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

FOUNDATION_EXPORT inline NSString * myInlineFunction(void); 
Cuestiones relacionadas