Использовать C ++ с какао вместо Objective-C? - PullRequest
120 голосов
/ 08 февраля 2009

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

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

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

Ответы [ 7 ]

108 голосов
/ 09 февраля 2009

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

Итак, у вас есть два варианта, если вы хотите поделиться кодом между приложениями C ++ на других платформах и вашим приложением на основе Cocoa. Во-первых, написать слой модели на C ++ и GUI в Какао. Это общий подход, используемый некоторыми очень большими приложениями, включая Mathematica . Ваш код C ++ может быть оставлен без изменений (вам не нужны «прикольные» расширения Apple для написания или компиляции C ++ в OS X). Ваш уровень контроллера, скорее всего, будет использовать Objective-C ++ (возможно, «фанковое» расширение Apple, на которое вы ссылаетесь). Objective-C ++ - это надмножество C ++, точно так же, как Objective-C - это надмножество C. В Objective-C ++ вы можете выполнять вызовы передачи сообщений в стиле objc (например, [some-objc-object callMethod];) изнутри функции C ++. И наоборот, вы можете вызывать функции C ++ из кода 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.

Второй вариант - использовать кроссплатформенный инструментарий 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 (в настоящее время в выпуск Candiate ) завершает этот переход и является 64-битным совместимым на OS X. Возможно, вы захотите взглянуть на источник Qt 4.5, если вы ' Вы заинтересованы в интеграции C ++ и API Какао.


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

64 голосов
/ 29 декабря 2012

Ну, это может звучать глупо, но на самом деле мы можем написать чистый код C ++ для создания GUI для 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;
}
17 голосов
/ 08 февраля 2009

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

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

9 голосов
/ 08 февраля 2009

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

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

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

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

Apple больше не публикует образцы, показывающие, как это сделать.

Есть отличное видео Питера Стейнбергера, размещенное в Realm. [Цель] C ++: что может быть не так? Я очень рекомендую всем, кто все еще использует Objective-C ++, и вы можете быстро просмотреть расшифровку. *

4 голосов
/ 08 февраля 2009

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

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

1 голос
/ 02 ноября 2014

Хотя это вопрос лет ...

Я пытался создать оболочку C ++ для некоторых классов Какао .

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

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

0 голосов
/ 01 марта 2010

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

...