Xcode: ссылка на проект C ++ из проекта Objective-C - PullRequest
1 голос
/ 29 июля 2011

Я начинаю ломать голову над этим, поэтому пришло время опубликовать здесь!

У меня есть проект C ++ в XCode, построенный как инструмент командной строки.Все файлы .cpp были переименованы в .mm, есть один .hh и несколько .h заголовков.Я указал «Скомпилировать источники как -> Objective-C ++» в настройках сборки.

У меня есть другой проект XCode для приложения для iOS.Для этого установлено значение «Компилировать источники как -> в соответствии с типом файла».Я не могу настроить его так, чтобы все компилировалось как Objective-C ++, поскольку некоторые части проекта не будут компилироваться как Obj-C ++.

В приложении iOS есть один класс, в котором я хочу использовать свой проект C ++и состоит из файлов MyClass.hh, MyClass.mm;они были просто .h и .m, но я переименовал их в надежде решить эту проблему.

Я перетащил свой проект cpp в проект iOS.Затем я добавил целевую зависимость на этапах сборки iOS, чтобы указать на приложение CLI cpp.

В MyClass.hh у меня есть

#include "../path/to/CppProject/ImportAll.h"

.., который является последовательным файлом заголовка, который последовательно 'Все заголовки include из проекта cpp.Затем я занимаюсь своими делами, создавая одно свойство в MyClass.hh, которое является указателем на объект cpp, и различные ссылки в классах MyClass.mm на классы cpp.Я получаю массу сообщений, относящихся к моим классам cpp, например:

MyCPPFile.h:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '<' token

Разве компилятор не распознает, что MyClass.hh - это Objective-C ++, а не Objective-C?Должен ли я иметь целевую зависимость, которая является библиотекой, а не указывать на это приложение CLI, возможно?

Я некоторое время гуглял, пытаясь решить проблему.Я видел ссылки на людей, использующих

#ifdef __cplusplus

, или же им приходится переименовывать файлы в .mm, чтобы все заработало, но в других случаях люди просто говорят, что перетаскивают проекты без проблем.

Может кто-нибудь, пожалуйста, просветить меня и объяснить, какие ключевые шаги я должен выполнить, чтобы сделать эту работу?Я был бы очень благодарен!Спасибо.

Ответы [ 2 ]

1 голос
/ 29 июля 2011

Спасибо всем, кто дал мне предложения.

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

Вот процесс:

Создание статической библиотеки C ++ и включение / связь с библиотекой Objective-C (например, приложение iOS) в XCode 4 :

  • В XCode 4 создайте новый проект типа статической библиотеки Cocoa Touch. В дальнейшем мы будем называть этот проект «CProj».
  • В рабочем пространстве CProj создайте / импортируйте столько классов C ++, сколько необходимо. Никакого специального суффикса для имен файлов не требуется - все мои файлы .h и .cpp.
  • В XCode создайте / откройте любой проект Objective-C, например. приложение для iOS. В дальнейшем мы будем называть этот проект «ObjProj».
  • Найдите CProj.xcodeproj в Finder (обычно это /Documents/CProj/CProj.xcodeproj), перетащите его на видимый значок проекта ObjProj в верхней части навигатора проекта XCode (видимая иерархия файлов / папок слева в XCode). Это теперь помещает CProj как вложенный проект в ObjProj.
  • Щелкните левой кнопкой мыши значок проекта ObjProj в Навигаторе проектов, справа появится новая панель, щелкните левой кнопкой мыши Фазы сборки на этой панели.
  • В разделе «Целевые зависимости» щелкните значок «+» и выберите значок библиотеки CProj под перечисленным проектом CProj. Нажмите ОК.
  • В разделе Link Binary With Libraries щелкните значок «+» и выберите значок библиотеки CProj в раскрывающейся папке Workspace в верхней части представленного окна.

Правила переименования файлов

  • Если в ObjProj включен заголовок CProj, используйте обратный путь для идентификации импорта, например, #include "../../MyProj/MyImport.h", чтобы перейти к шагу 2 назад и перейти в папку MyProj.

  • Любой файл реализации ObjProj, включая заголовок CProj, должен быть переименован из .m в .mm. Любой заголовочный файл ObjProj, включая заголовок CProj, должен быть переименован из .h в .hh.

  • Любой файл ObjProj, включая файл с суффиксом теперь .hh (следствие вышеприведенного шага), должен быть переименован аналогичным образом.

Пример: Считайте, что у вас есть файлы A.h, A.m, B.h, B.m. A.m импортирует B.h, а B.h включает один или несколько заголовков CProj. B.m включает ссылки на типы, используя классы CProj, включенные через B.h. Первое переименование: B.h -> B.hh, так как оно содержит include. Затем B.m -> B.mm, так как он содержит ссылки на типы для CProj (нет необходимости включать, поскольку B.h уже сделал их). Тогда A.m -> A.mm, так как A.m, который содержал включение для B.h, теперь имеет включение для переименованного файла, B.hh.

P.S. Обратите внимание, что библиотека C ++ не любит автоматически перестраивать, когда это необходимо - мне часто приходится «очищать», а затем «собирать» в ObjProj после обновления из него CProj.

0 голосов
/ 29 июля 2011

Похоже, суть вашей проблемы заключается в следующем:

Разве компилятор не распознает, что MyClass.hh является Objective-C ++, а не Objective-C?

Компилятор не признает, что MyClass.hh является кодом Objective-C ++.Или любой другой код; компилятор никогда не видит MyClass.hh (по всей вероятности).

По умолчанию файлы заголовков никогда не передаются компилятору по умолчанию.Только исходные файлы (.cpp, .m, и так далее) - препроцессор, который запускается для этих файлов, приводит к преобразованию, которое содержит исходный файл плюс все включенные заголовки и разрешенные макросы.

Итак, проблема в том, что у вас, вероятно, есть исходный файл .mm, который импортирует MyClass.hh, который, в свою очередь, включает заголовочный файл C ++.Но компилятор пытается скомпилировать полученный модуль перевода как Objective-C ++ и встречает некоторые специфические для C ++ вещи в этом заголовке.На самом деле, я подозреваю, что эта проблема не имеет ничего общего с дополнительными целевыми зависимостями и с тем, что вы настроили: я думаю, вы могли бы воспроизвести ее минимально с очень простым приложением Objective-C ++, которое включает в себя заголовок.Вы должны попробовать это и посмотреть, это либо подтвердит мою теорию (в конце концов, я просто размышляю, поскольку вы не показали достаточно источника, чтобы я мог знать наверняка), либо покажет, что проблема в другом месте.

Решение, вероятно, состоит в том, чтобы использовать средства защиты препроцессора, такие как #ifdef __cplusplus (здесь есть полезный каталог предопределенных символов здесь ), чтобы скрыть специфичный для C ++ код от компилятора Objective-C ++ (или наоборот в некоторых случаях).).Обратите внимание, что это может быть трудно или невозможно сделать на основе фактического содержимого заголовка.

...