Использование статических библиотек C / C ++ из приложений iPhone ObjectiveC
============================================================================

Возможно ли иметь API статической библиотеки C, которая использует C ++ для внутреннего использования и скрывает это от пользователей библиотеки?

Я написал переносимую библиотеку C ++, которую я хотел бы статически связать с приложением iPhone.

Я создал проект XCode, используя шаблон «статической библиотеки» Max OS X, и скопировал исходный код, а также написал C-ваппер (для обработки исключений), используя (extern «C»).

Я пытаюсь использовать сгенерированную библиотеку (файл .a) в другом приложении Cocoa iPhone.

Все работает хорошо, если я использую расширения (.mm) в вызывающем файле ObjectiveC и (.cpp) в классе реализации в библиотеке.

Но я получаю неразрешенные символы при связывании, когда пытаюсь изменить файл оболочки на расширение (.c), даже если все файлы функций оболочки являются только Си-функциями.

Просто потому, что C ++ используется внутри библиотеки, означает ли это, что внешне он все еще должен рассматриваться как программа C ++. Разве нет в любом случае для обеспечения этой абстракции?

**Редактировать:** Спасибо за ответы,

Я использовал extern «C», я просто не был уверен в том, какие конфигурации нужны в вызывающем проекте. то есть. если предполагаемый вызов потребует знать, использует ли он C ++ или может быть невежественным, и думать, что это чисто библиотека C.

Казалось бы, я не могу, и я должен использовать (.mm) файлы на моих классах ObjectiveC.

Это слишком сложно сделать в комментариях, поэтому я просто собираюсь показать вам, какие проблемы с ссылками у вас возникают. Когда XCode встречает файлы, он использует правила сборки, основанные на суффиксе, чтобы решить, какой компилятор использовать. По умолчанию gcc связывает файлы со стандартной библиотекой C, но не связывает со стандартной библиотекой C ++. Архивные файлы (статические библиотеки) вообще не имеют разрешения на связывание. В основном это архив объектных файлов, которыедолжны быть связаны, Поскольку в вашем проекте нет файлов .mm или .cpp, g ++ никогда не вызывается, а ваши файлы никогда не связаны со стандартными библиотеками. Чтобы исправить это, просто добавьте стандартные библиотеки C ++ к вашим другим флагам компоновщика в вашем проекте XCode или просто добавьте их в предопределенную опцию других флагов как -l (например, -lstdc ++).

Вот быстрая демонстрация:

stw.h:

stw.cpp:

Постройте библиотеку:

Использование библиотеки из приложения C:

myapp.c:

Сборка приложения C:

Если вы попытаетесь скомпилировать без -lstdc ++, вы получите все нерешенные проблемы, потому что компилятор C не имеет абсолютно никакого представления о том, что он должен ссылаться на среду выполнения C ++ (и почему это так, верно!?!?), Поэтому вы должны добавить это вручную. Другой вариант, который у вас есть, это изменить правило сборки для вашего проекта ... вместо того, чтобы Xcode использовал gcc для сборки файлов .c и .m, скажите ему использовать g ++, и ваши проблемы будут решены.



Вы должны объявить функции, которые вы хотите видеть`extern "C"`, Их подписи должны быть C-совместимыми, а содержимое - нет (например, вы можете обращаться к объектам C ++, но не можете передавать их напрямую; указатели в порядке). Символы будут видны любой C-совместимой среде.

РЕДАКТИРОВАТЬ: И скомпилировать его как исходный файл C ++, C не имеет понятия языковой связи. Есть пара других проблем с языковой связью (например, тот факт, что все`extern "C"` функции с одинаковыми именами являются одной и той же функцией, независимо от пространства имен).

EDIT2: в шапке вы можете проверить макрос`__cplusplus`и используйте это для установки для C ++ и других языков соответственно (потому что C ++ потребует`extern "C"` декларации и другие языки, вероятно, будут жаловаться на них).



В основном, когда вы компилируете функции C с помощью компилятора C ++, он обрабатывает имена функций и использует ABI C ++.

Когда вы используете расширение * .cpp или * .mm, вы используете компилятор C ++.

То, что вы хотите сделать, это заставить компилятор генерировать функции C с именами, не являющимися искажениями, и использовать C ABI.

Вы можете сделать это одним из следующих способов:

Компилировать с помощью компилятора C.Скомпилируйте с помощью компилятора C ++, но убедитесь, что вы используете префикс объявления функций с помощью extern "C"Любимый способ настроить файл заголовка, чтобы один и тот же файл мог быть включен из исходных файлов C и C ++, это:



спасибо за такую хорошую дискуссию.

что я сделал, это:

1) Я создал статический lib, используя опцию cocaotouch static lib. В этом у меня есть c / c ++ / obj-c все смешать. тем не менее, мой экспорт только классы obj-c. Фактически я использовал objc- to C ++.

2) Затем я создал приложение для iphone в X-Code Proj. Я добавил другие ссылки, помечает мое имя библиотеки (-lxyz) // мое имя библиотеки libxyz.a Я добавил путь поиска lib, путь поиска заголовка

3) потом я скомпилировал. Я получил ошибки. Говорят, новый оператор, оператор удаления не найден.

3) затем, кроме моего приложения applelegate, контроллера представления, я добавил фиктивную cpp (.h, .cpp) ... atestdummy.h atestdummy.cpp

4) потом строю заново ...

вот это сработало.

Так что - все предложения, которые они давали ранее, работали на меня. основная причина, если ваше приложение не увидит .cpp файл .mm файл с кодом cpp, связанный не будет использовать g ++.

Спасибо всем. Я прочитал выше и решил мою проблему.

ребята, вы можете поделиться.