Использовать С++ с Cocoa Вместо Objective-C?

Я бы хотел написать приложения, использующие С++ и фреймворки Cocoa, потому что Apple не делает 64-битную Carbon. С++ кажется довольно ванильным в своей реализации в Linux и Windows, но в Mac OS X кажется, что требуются дополнительные фрагменты кода Apple (например, обертка Obj-C). Также кажется, что Apple заставляет разработчиков писать в Objective-C, а не в С++, хотя я мог ошибаться.

Я пытаюсь найти путь для написания кода на Mac, который будет легко поддерживать кросс-платформу. Необходимость писать код в С++ для Linux/Windows, а затем переписать большие части в Objective-C будет очень неэффективной.

Есть ли способ написать код на С++, который будет поддерживаться в будущем и поддерживается в Xcode? Кроме того, если это возможно, как бы я смешивал С++ и Objective-C в Xcode? Спасибо.

Ответ 1

Вы не можете полностью написать приложение Cocoa на С++. Cocoa в значительной степени опирается на возможности позднего связывания Objective-C для многих своих основных технологий, таких как привязки ключевых значений, делегаты (стиль Cocoa) и шаблон целевого действия. Для поздних требований привязки очень сложно реализовать API Cocoa во время привязки к компиляции, набранный язык, такой как С++ ⁱ. Вы можете, конечно, написать чистую С++-приложение, которая работает на OS X. Она просто не может использовать API Cocoa.

Таким образом, у вас есть два варианта, если вы хотите использовать код между приложениями С++ на других платформах и вашим приложением Cocoa. Во-первых, написать слой модели в С++ и графический интерфейс в Cocoa. Это общий подход, используемый некоторыми очень крупными приложениями, включая Mathematica. Ваш код на С++ можно оставить без изменений (вам не нужны "фанковые" расширения Apple для написания или компиляции С++ в OS X). Возможно, ваш уровень контроллера будет использовать Objective-C ++ (возможно, "фанковое" расширение Apple, на которое вы ссылаетесь). Objective-C ++ - это надмножество С++, так же как Objective-C является надмножеством C. В Objective-C ++ вы можете выполнять вызовы передачи сообщений в стиле objc (например, [some-objc-object callMethod];) из функции С++. И наоборот, вы можете вызывать функции С++ из кода ObjC, например:

@interface MyClass {
    MyCPPClass *cppInstance;
}
@end

@implementation MyClass
- (id)init {
    if(self = [super init]) {
        cppInstance = new MyCPPClass();
    }
    return self;
}
- (void) dealloc {
    if(cppInstance != NULL) delete cppInstance;
    [super dealloc];
}
- (void)callCpp {
    cppInstance->SomeMethod();
}
@end

Вы можете узнать больше о Objective-C ++ в Objective-C языке guide. Тогда слой вида может быть чистым Objective-C.

Второй вариант - использовать кросс-платформенный инструментарий С++. Инструмент Qt может соответствовать законопроекту. Кросс-платформенные инструментальные средства, как правило, презирают пользователи Mac, потому что они не получают все подробные сведения о деталях в точности, и пользователи Mac ожидают, что польза в пользовательских интерфейсах приложений Mac. Однако Qt делает удивительно хорошую работу, и в зависимости от аудитории и использования вашего приложения она может быть достаточно хорошей. Кроме того, вы потеряете некоторые из технологий, специфичных для OS X, таких как Core Animation и некоторые функции QuickTime, хотя в Qt API есть приблизительные замены. Как вы указываете, Carbon не будет перенесен на 64-битный. Поскольку Qt реализован на API-интерфейсах Carbon, Trolltech/Nokia пришлось переносить Qt на API Cocoa, чтобы сделать его совместимым с 64-разрядными. Я понимаю, что следующее отношение Qt (в настоящее время в релиз-релиз) завершает этот переход и совместим с 64-битной версией OS X. Вы можете хотите взглянуть на источник Qt 4.5, если вы заинтересованы в интеграции С++ и API Cocoa.


ⁱ Некоторое время Apple создавала API Cocoa, доступный для Java, но мост требовал обширной ручной настройки и не мог обрабатывать более совершенные технологии, такие как привязки ключевых значений, описанные выше. В настоящее время динамически типизированные языки, такие как Python, Ruby и т.д., Являются единственным реальным вариантом для написания приложения Cocoa без Objective-C (хотя, конечно, эти мосты используют Objective-C под капотом).

Ответ 2

Ну, это может показаться глупым, но на самом деле мы можем написать чистый код на С++ для создания графического интерфейса для Mac OS X, но мы должны связать его с инфраструктурой Cocoa.

/*
 * test1.cpp
 * This program shows how to access Cocoa GUI from pure C/C++
 * and build a truly functional GUI application (although very simple).
 * 
 * Compile using:
 *   g++ -framework Cocoa -o test1 test1.cpp
 *
 * that will output 'test1' binary.
 */


#include <CoreFoundation/CoreFoundation.h>
#include <objc/objc.h>
#include <objc/objc-runtime.h>
#include <iostream>

extern "C" int NSRunAlertPanel(CFStringRef strTitle, CFStringRef strMsg,
                               CFStringRef strButton1, CFStringRef strButton2, 
                               CFStringRef strButton3, ...);


int main(int argc, char** argv)
{
    id app = NULL;
    id pool = (id)objc_getClass("NSAutoreleasePool");
    if (!pool)
    {
        std::cerr << "Unable to get NSAutoreleasePool!\nAborting\n";
        return -1;
    }
    pool = objc_msgSend(pool, sel_registerName("alloc"));
    if (!pool)
    {
        std::cerr << "Unable to create NSAutoreleasePool...\nAborting...\n";
        return -1;
    }
    pool = objc_msgSend(pool, sel_registerName("init"));

    app = objc_msgSend((id)objc_getClass("NSApplication"),
                       sel_registerName("sharedApplication"));

    NSRunAlertPanel(CFSTR("Testing"),
                    CFSTR("This is a simple test to display NSAlertPanel."),
                    CFSTR("OK"), NULL, NULL);

    objc_msgSend(pool, sel_registerName("release"));
    return 0;
}

Ответ 3

Да, вы можете просто использовать С++ (то есть записывать его в *.cpp файлы) и даже смешивать файлы С++ и Objective-C внутри *.mm(стандартный Objective-C код хранится в файлах *.m).

Конечно, вам все равно придется использовать Objective-C для вашего пользовательского интерфейса и создать обертки Objective-C для ваших объектов на С++. Другим вариантом является переход на Qt, который является С++ Framework, который поддерживает Windows, Mac OS X и Linux, и будет выпущен под LGPL со следующей версией 4.5.

Ответ 4

Да, вы можете их смешивать.

Вам нужно использовать Objective-C для непосредственной работы с вашими объектами графического интерфейса пользователя и получать уведомления от них.

Эти объекты Objective-C могут напрямую вызывать логику С++, если вы помещаете их в .mm файлы вместо чистых Objective-C.m файлов. Обратите внимание, что вы можете увидеть более старый совет, предлагающий использовать прописную букву .M, чтобы указать Objective-C ++, но это очень шелушащийся и, вероятно, смущает вас, а также компилятор.

Вам не нужно обертывать каждый объект С++, но ваш код Objective-C должен содержать указатели на них.

Apple имеет полный образец Cocoa с Carbon или CPP. с более подробной информацией в readme.

Ответ 5

Если вы просто хотите использовать простой ванильный С++, это абсолютно поддерживается и не отличается от любой другой платформы. Xcode даже имеет шаблон для него в меню "Файл" > "Новый проект" > "Утилита командной строки" > "Инструмент С++". Кроме того, ряд популярных библиотек с открытым исходным кодом (libcurl, libxml2, sqlite и т.д.) Поставляются с OS X и доступны для динамической компоновки. Вам не нужно использовать Cocoa или что-нибудь конкретное для Apple, если вы этого не хотите.

Если вы хотите использовать Cocoa в определенных частях вашего приложения, посмотрите Objective-C ++. Вы можете смешать С++ и Objective-C в том же файле, предоставив ему расширение .mm или щелкнув правой кнопкой мыши по файлу в Xcode и выбрав Get Info > General, а затем изменив тип файла на sourcecode.cpp.objcpp. Второй вариант полезен, если у вас есть .cpp файл, в котором вы хотите использовать Objective-C в пределах #ifdef для Mac.

Ответ 6

Хотя это старый вопрос...

У меня попытался сделать С++-оболочку некоторых классов Cocoa.

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

В любом случае мой проект был окончательно оставлен из-за объявления Swift. Он очистил все причины, по которым я хотел сначала использовать С++, и обеспечивает еще больше и лучше.

Ответ 7

Если вы пишете чисто графическое приложение, т.е. рисуете все с помощью кода, рассмотрите openFrameworks. Это языки программирования с открытым исходным кодом, построенные поверх C/С++. Он addons, который позволяет людям расширять язык. У них аддон для iphone. Я считаю, что он поставляется с библиотекой и проектами XCode, которые помогут вам скомпилировать приложения для iPhone и iPod touch.