Цель C: встроенная функция - символ не найден - PullRequest
12 голосов
/ 18 августа 2010

У меня есть библиотека, которая использует встроенную функцию C и прекрасно компилируется.Когда другая библиотека ссылается на эту библиотеку, она все равно хорошо компилируется.Но если реальное приложение ссылается на библиотеку, оно не может скомпилировать, говоря, что символ _functionNameHere (да, имя функции, начинающееся с подчеркивания) не найден.

Если я удаляю встроенный спецификатор, все прекрасно скомпилируется,Но пока функция встроена в библиотеку, приложение не может компилироваться!

Есть идеи, почему это так?

Я знаю довольно много о компиляторах, но я новичок вObjective-C, и все, что я знаю об этом, является не чем иным как образованными догадками.И даже таким образом я не могу придумать причину, по которой он будет вести себя таким образом.

Дело в том, что встроенная функция - это INLINE, что означает, что символа вообще нет, он компилируется внутри строки, где бы он ни находился.называется, и приложение, ссылающееся на него, даже не должно знать, что оно когда-либо существовало.Это верно до тех пор, пока встроенная функция всегда встраиваема и доступна для библиотеки, и нет специальной конфигурации компилятора, которая бы запрещала встраивание, и все это верно.

Итак, кто угодно, приходите иуказывать пальцем на то, что я делаю / неправильно думаю ...

Спасибо: -)

Ответы [ 2 ]

36 голосов
/ 26 августа 2010

Вы должны добавить спецификатор static к определению встроенной функции, если функция предназначена для использования только в той же единице перевода (внутренняя связь),

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

Если вы опустите static в приведенном выше примере (в конфигурации отладки, когда оптимизация не выполняется и не выполняется встраивание), компоновщик завершит работу с ошибкой, сообщив, что на _add ссылаются, но символ (ы) не найден.

В C99 объявление встроенной функции без какого-либо спецификатора хранилища не будет генерировать фактическое тело вызываемой функции, поэтому компоновщик выдает ошибку, когда она необходима.

Если ваша встроенная функция может использоваться другими модулями,это сложнее.Обычной практикой является включение определения встроенной функции (без extern) в заголовочный файл и включение ровно одного объявления прототипа с extern точно в одном модуле.

Хорошая статья, объясняющая встроенные функции в C99: http://www.drdobbs.com/184401540

0 голосов
/ 07 октября 2015

просто добавьте FOUNDATION_EXPORT для работы с заголовком (.h). Вспомните, как импортировать Foundation / Foundation.h (OS X) или UIKit / UIKit.h (ios).

Пример:

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

FOUNDATION_EXPORT inline NSString * myInlineFunction(void);
...