Використовуйте C ++ з какао замість Objective-C?


122

Я хотів би писати програми, які використовують C ++ і какао-каркаси, тому що 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? Дякую.

Відповіді:


110

Ви не можете написати заявку на какао повністю на C ++. Какао в значній мірі покладається на пізні можливості зв’язування Objective-C для багатьох його основних технологій, таких як Прив'язка Ключових Значень, Делегатів (стиль Какао) та Цільова дія. Вимоги до пізнього прив'язування дуже ускладнюють реалізацію API Cocoa в мові, яка вводить час компіляції, набраною мовою, як C ++ ⁱ Звичайно, ви можете написати чистий додаток C ++, який працює на OS X. Він просто не може використовувати API какао.

Отже, у вас є два варіанти, якщо ви хочете поділитися кодом між додатками C ++ на інших платформах та вашим додатком на основі какао. Перший - написати шар моделі на C ++ та GUI у какао. Це загальний підхід, який застосовують деякі дуже великі програми, зокрема Mathematica . Ваш код C ++ можна залишити без змін (для запису чи компіляції 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 . Потім шар перегляду може бути чистим Objective-C.

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


Apple На деякий час Apple зробила Java доступним для API какао, але міст потребував широкої налаштування вручну, і він не зміг впоратися з більш передовими технологіями, такими як "Ключові значення", описані вище. В даний час динамічно типізовані мови, пов’язані з виконанням часу, такі як Python, Ruby і т. Д. - єдиний реальний варіант написання програми для какао без Objective-C (хоча, звичайно, ці мости використовують під кришкою Objective-C).


Я зараз намагаюся перенести моє невелике додаток Ogre3D, здається ДУЖЕ болісним. Apple намагається перетворити всіх на Objc, чи це справді особливість?
jokoon

68

Ну, це може здатися нерозумним, але насправді ми можемо написати чистий код 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
Це чудово. Чи є більш складні приклади? Наприклад, відкрити вікно NSW?
imallett

test1.cpp: У функції 'int main (int, char **)': test1.cpp: 26: 48: помилка: не вдається перетворити 'Class {aka objc_class *}' в 'id {aka objc_object *}' в ідентифікаційному ідентифікаторі pool = objc_getClass ("NSAutoreleasePool"); ^ test1.cpp: 41: 61: помилка: не вдається перетворити 'Class {aka objc_class *}' в 'id {aka objc_object *}' для аргументу '1' в 'objc_object * objc_msgSend (id, SEL, ...)' sel_registerName ("sharedApplication")); ^
Jichao

6
@Jichao см сумісність Clang з внутрішніми типами Objective-C - виправлення проста: замінити objc_getClassз(id)objc_getClass
Дмитро Ісаєв

Як я можу використовувати std :: string для встановлення напр. назва для панелі попередження? Я спробував використовувати c_str () і так, але нічого не
вийшло

1
Це більше не
збирається

18

Так, ви можете просто використовувати 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.


23
Зауважте, що якщо ви використовуєте Qt, ваш додаток буде смоктати. Програми на основі Qt не виглядають як рідні програми для Mac. (Для прикладу див. Google Планета Земля.)
Пітер Хосей

15
Петро: Це зовсім не так. Програми, засновані на Qt, можуть виглядати ідентично рідним додаткам для Mac, вам просто потрібно виконати налаштування на платформі, що набагато простіше, ніж писати власний графічний інтерфейс на кожній платформі.
Майк МакКвайд

12
Майк, ти дезінформований. Серед інших їхніх недоліків додатки на основі Qt на mac взагалі не використовують вбудовані елементи керування, а бібліотека Qt робить сам малюнок. Це означає, що додатки Qt не отримують апаратного прискорення для 2D-рендерінгу, вони не залишаються синхронізованими зі змінами інтерфейсу користувача, які Apple вносить до стандартних елементів керування, а додаток Qt не може забезпечити відповідність або сценарій ADA, якщо ви не винаходите ці колеса самі. Іншими словами, НЕ ПІДТРИМУЙТЕ надсилати додаток Qt на Mac. Google може відмовитися від цього: ви не можете.
NSResponder

13
Вони користуються нативними елементами управління, тому Qt має версію какао та вуглецю. У нього є інші проблеми, але багато людей доставляють додатки Qt на Mac, і вони прекрасно працюють (і ідеально, трохи налаштувавшись).
Майк МакКвайд

2
Тільки використання нативного керування не означає, що це виглядатиме і відчуватиметься як рідні програми. Те, що викликає рідне відчуття, - це різниця кожної ОС. Якщо ви налаштуєте додаток так, щоб він відчував себе на певній платформі, він не буде відчуватися рідним на іншій платформі. А точне налаштування невеликих форм поведінки на колись абстрагованому шарі завжди важче, ніж це робити на рідному шарі.
eonil

9

Так, ви можете їх змішати.

Вам потрібно використовувати Objective-C, щоб безпосередньо діяти над вашими об’єктами GUI та отримувати від них сповіщення.

Ці об'єкти Objective-C можуть безпосередньо викликати логіку C ++, якщо ви вводите їх у .mm-файли замість чистих файлів Objective-C .m. Зауважте, що, можливо, ви побачите (набагато) старі поради, що пропонують використовувати великі регістри .M для позначення Objective-C ++, але це дуже невдало і може заплутати вас, а також компілятора.

Вам не потрібно обертати кожен об'єкт C ++, але ваш код Objective-C повинен містити покажчики на них.

Apple більше не публікує жодних зразків, що показують, як це зробити.

Є чудове відео Пітера Штейнбергера, яке відбулося в Realm [Objective] C ++: Що могло б помилитися? Я настійно рекомендую всім, хто все ще використовує Objective-C ++, і ви можете швидко знехтувати стенограму.


@SteveS ваше посилання також порушено
fferri

@fferi - Посилання Steinberger вище виправлено. Інтеграція вуглецю какао була з 2007 року від developer.apple.com, Apple видалила її. Це вказує на те, що РЕАЛЬНО не слід писати новий код за допомогою API Carbon. На даний момент навіть підтримувати існуючий код за допомогою Carbon ризиковано. Зверніться до прийнятої відповіді на це питання, або на цю, якщо вам потрібно змішати C ++ / Ціль C, але ви не повинні використовувати Carbon. Це сказало, ось: інтеграція вуглецю та какао
SteveS

4

Якщо ви просто хочете використовувати звичайну ваніль C ++, це абсолютно підтримується і насправді не відрізняється від будь-якої іншої платформи. У Xcode навіть є шаблон для нього в розділі Файл> Новий проект> Утиліта командного рядка> Інструмент C ++. Крім того, ряд популярних бібліотек з відкритим кодом (libcurl, libxml2, sqlite тощо) постачаються з OS X і доступні для динамічного посилання. Вам не потрібно використовувати какао чи що-небудь, що стосується Apple, якщо ви цього не хочете.

Якщо ви хочете використовувати какао в певних частинах програми, подивіться на Objective-C ++ . Ви можете змішати C ++ та Objective-C в одному файлі, надавши йому розширення .mm або клацнувши правою кнопкою миші файл у Xcode та вибравши Отримати інформацію> Загальне, а потім змінити Тип файлу на sourcecode.cpp.objcpp. Другий варіант корисний, якщо у вас є .cpp файл, де ви хочете використовувати Objective-C в специфічному для Mac #ifdef.


1
BTW, (дійсно корисний) шаблон C ++ відсутній з останніми версіями Xcode (4.x і 5.x)
Jay

1

Хоча це запитання років ...

Я спробував зробити обгортку C ++ з деяких класів какао .

Це був досить приємний досвід. C ++ забезпечив кращу безпеку типу, ніж Objective-C, і змусив мене писати менше коду. Але час компіляції та безпека пам’яті гірші. Це можливо, але деякі функції, засновані на динаміці, були непрості в обробці. Я думаю, що не має сенсу займатися цим на C ++.

У будь-якому випадку мій проект був остаточно відмовлений через оголошення Swift. Це очистило всі причини, з яких я хотів спочатку використовувати C ++, і надає ще більше і краще.


0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.