2010-08-18 13 views
12

Mam bibliotekę, która używa wbudowanej funkcji C, i kompiluje się dobrze. Gdy inna biblioteka odwołuje się do tej biblioteki, nadal dobrze się kompiluje. Ale jeśli rzeczywista aplikacja odwołuje się do biblioteki, nie kompiluje się, mówiąc, że _functionNameHere (tak, nazwa funkcji zaczynająca się od podkreślenia) - nie znaleziono symbolu.Cel C: Funkcja Inline - nie znaleziono symbolu

Po usunięciu specyfikatora śródliniowego wszystko się zgadza. Ale dopóki funkcja jest wbudowana wewnątrz biblioteki, aplikacja nie może się skompilować!

Jakieś pomysły, dlaczego tak jest?

Wiem dużo o kompilatorach, ale jestem nowy w Objective-C, a wszystko, co wiem na ten temat, nie jest niczym więcej jak tylko wykształconymi domysłami. I nawet w ten sposób nie mogę wymyślić powodu, który będzie się tak zachowywał.

Chodzi o to, że wbudowana funkcja to INLINE, co oznacza, że ​​nie ma w ogóle żadnego symbolu, jest kompilowana inline, gdziekolwiek się ona nazywa, a aplikacja odwołująca się nie powinna nawet wiedzieć, że kiedykolwiek istniała. Jest to prawdą, o ile funkcja inline jest zawsze w stanie, i jest prywatna dla biblioteki, i nie ma specjalnej konfiguracji kompilatora, która uniemożliwia wstawianie, a wszystkie z nich są prawdziwe.

Więc ktoś proszę przyjść i wskazać palcem na co robię/myślenie źle ...

Dzięki :-)

Odpowiedz

36

należy dodać statycznego specyfikator do definicji funkcji inline Jeśli funkcja jest przeznaczona do użytku tylko w tej samej jednostce tłumaczeniowej (połączenie wewnętrzne),

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

Jeśli pominąć statycznego w powyższym przykładzie (w Debug configur Jeśli nie zostanie wykonana żadna optymalizacja i nie zostanie przeprowadzone wpisywanie), linker zakończy działanie z błędem narzekającym _add jest odwołany, ale nie znaleziono symboli.

W C99 deklaracja funkcji wbudowanej bez specyfikatora pamięci nie wygeneruje rzeczywistej treści funkcji do wywoływania, więc linker podaje błąd, gdy jest potrzebny.

Jeśli twoja funkcja inline może być używana przez inne moduły, jest to bardziej skomplikowane. Powszechną praktyką jest dołączanie definicji pliku śródliniowego (bez danych zewnętrznych) do pliku nagłówkowego i dołączenie dokładnie jednej deklaracji prototypu z danymi zewnętrznymi w dokładnie jednym module.

Dobry artykuł wyjaśniający funkcji wbudowanych w C99: http://www.drdobbs.com/184401540

+0

Arrix - właśnie testowanie oparte na tym, co wyjaśniono tutaj. Jeśli dodaję "podwójne radiany w linii (podwójne stopnie) {stopnie zwrotu * M_PI/180; } 'na początek pliku ViewController.m następnie wywołaj radians() w metodzie w tym pliku, otrzymuję błąd linkera, mimo że ustawiłem moją konfigurację na Release. Z pewnością w tym przypadku funkcja s/be jest wbudowana, a więc słowo kluczowe static nie jest konieczne? – Brynjar

0

wystarczy dodać FOUNDATION_EXPORT funkcjonować w nagłówku (.h). Zapamiętaj import Foundation/Foundation.h (OS X) lub UIKit/UIKit.h (ios).

Przykład:

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

FOUNDATION_EXPORT inline NSString * myInlineFunction(void);