Używać C++ Z Cocoa zamiast Objective-C?

Chciałbym pisać aplikacje, które używają C++ i frameworków Cocoa, ponieważ Apple nie robi z Carbon 64-bitowych możliwości. C++ wydaje się być dość waniliowy w swojej implementacji na Linuksie i Windows, ale na Mac OS X wydaje się, że dodatkowe kawałki kodu Apple są wymagane (jak Obj-C wrapper). Wydaje się też, że Apple zmusza programistów do pisania w Objective-C, a nie c++, chociaż mogę się mylić.

Próbuję znaleźć ścieżkę do napisania kodu na komputerze Mac, który byłby łatwy do utrzymania na różnych platformach. Pisanie kodu w C++ dla Linuksa/Windows, a następnie przepisywanie dużych części w Objective-C byłoby bardzo nieefektywne.

Czy istnieje sposób na napisanie kodu w C++, który będzie obsługiwany w przyszłości i obsługiwany w Xcode? Ponadto, jeśli jest to możliwe, jak wymieszać C++ i Objective-C w Xcode? Dzięki.

Author: spaaarky21, 2009-02-08

7 answers

Nie można napisać aplikacji Cocoa w całości w C++. Cocoa opiera się w dużej mierze na możliwościach późnego wiązania Objective-C dla wielu jego podstawowych technologii, takich jak wiązania wartości klucza, delegatów (styl Cocoa) i wzorca działania celu. Późne wymagania wiążące sprawiają, że implementacja API Cocoa jest bardzo trudna do zaimplementowania w skompilowanym, typowanym języku, takim jak C++ⁱ. Możesz oczywiście napisać czystą aplikację C++, która działa na OS X. Po prostu nie może używać interfejsów API Cocoa.

Więc, masz dwie opcje, jeśli chcesz udostępnić kod między aplikacjami C++ na innych platformach a aplikacją opartą na Cocoa. Pierwszym z nich jest zapisanie warstwy modelu w C++ i GUI w Cocoa. Jest to powszechne podejście używane przez niektóre bardzo duże aplikacje, w tym Mathematica. Twój kod C++ może pozostać niezmieniony(nie potrzebujesz "funky" rozszerzeń apple, aby pisać lub kompilować C++ na OS X). Twoja warstwa kontrolera prawdopodobnie będzie korzystać z Objective-C++ (być może "funky" rozszerzenie Apple, do którego się odnosisz). Objective-C++ jest supersetem języka C++, podobnie jak Objective-C jest supersetem języka C. W Objective-C++ można wywoływać komunikaty w stylu objc (np. [some-objc-object callMethod];) z poziomu funkcji C++. Z drugiej strony, możesz wywoływać funkcje C++ z kodu ObjC, takie jak:

@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
Więcej informacji na temat Objective-C++ można znaleźć w przewodniku Objective-C language . Warstwa widoku może być czysta Objective-C.

Drugą opcją jest użycie wieloplatformowego zestawu narzędzi C++. Zestaw narzędzi Qt może pasować do rachunku. Wieloplatformowe Zestawy narzędzi są ogólnie pogardzane przez użytkowników komputerów Mac, ponieważ nie mają dokładnie wszystkich szczegółów wyglądu i stylu, a użytkownicy komputerów Mac oczekują Polskiego w interfejsie aplikacji Mac. Qt robi jednak zaskakująco dobrą robotę i w zależności od odbiorców i korzystania z aplikacji może być wystarczająco dobra. Ponadto stracisz niektóre technologie specyficzne dla OS X, takie jak Core Animation i niektóre funkcje QuickTime, chociaż istnieją przybliżone zamienniki w Qt API. Jak zaznaczasz, Carbon nie zostanie przeniesiony na 64-bit. Ponieważ Qt jest zaimplementowane na interfejsach API Carbon, Trolltech/Nokia musiał przenieść Qt do interfejsu Cocoa, aby był zgodny z 64-bitowym interfejsem. Rozumiem, że kolejna relase Qt (obecnie w release candiate) kończy to przejście i jest 64-bitowa kompatybilna z OS X. Możesz chcieć rzucić okiem na źródło Qt 4.5, jeśli jesteś zainteresowany integracją C++ i interfejsów API Cocoa.


ⁱ przez jakiś czas Apple robiło Cocoa API dostępne dla Javy, ale most wymagał rozległego strojenia ręcznego i nie był w stanie obsłużyć bardziej zaawansowanych technologii, takich jak wiązania klucz-wartość opisane powyżej. Obecnie dynamicznie typowane, związane z uruchomieniem języki, takie jak Python, Ruby, itp. są jedyną realną opcją pisania aplikacji Cocoa bez Objective-C (choć oczywiście te mosty używają Objective-C pod maską).

 111
Author: Barry Wark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-18 01:43:19

Cóż, może to zabrzmieć głupio, ale w rzeczywistości możemy napisać czysty kod C++, aby stworzyć GUI dla Mac OS X, ale musimy połączyć się z Cocoa framework.

/*
 * 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;
}
 68
Author: FX. J. Adi Lima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-02 12:51:24

Tak, możesz po prostu użyć C++ (tzn. napisać go w *.pliki cpp), a nawet wymieszać C++ i Objective-C wewnątrz plików*. mm (standardowy kod Objective-C jest przechowywany w*.pliki m).

Oczywiście, nadal musisz używać Objective-C dla swojego interfejsu użytkownika i tworzyć Objective-C wrappery dla obiektów C++. Inną opcją jest przejście na Qt , który jest frameworkiem C++, który obsługuje Windows, Mac OS X i Linux-i zostanie wydany pod LGPL w następnej wersji 4.5.

 18
Author: fhe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 11:39:29

Tak, możesz je mieszać.

Musisz użyć Objective-C, aby bezpośrednio operować na obiektach GUI i otrzymywać od nich powiadomienia.

Obiekty Objective-C mogą bezpośrednio wywoływać logikę C++, Jeśli umieścisz je w plikach. mm, zamiast czystego Objective-C .pliki M. Zauważ ,że możesz zobaczyć (dużo) starsze porady sugerujące użycie wielkiej litery .M, aby wskazać Objective-C++, ale jest to bardzo flaky i może mylić zarówno Ciebie, jak i kompilator.

Nie musisz owijać każdego każdy obiekt C++ oprócz kodu Objective-C będzie musiał zawierać wskaźniki do nich.

Apple nie publikuje już żadnych próbek pokazujących, jak to zrobić.

W Realm [Objective] C++ jest świetny filmik Petera Steinbergera: co może pójść nie tak? Gorąco polecam wszystkim, którzy nadal używają Objective-C++ i można szybko przejrzeć transkrypcję.

 9
Author: Andy Dent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 18:05:48

Jeśli po prostu chcesz używać plain vanilla C++, jest to absolutnie obsługiwane i tak naprawdę nie różni się od jakiejkolwiek innej platformy. Xcode ma nawet szablon dla niego w Plik > Nowy Projekt > narzędzie wiersza poleceń > narzędzie C++. Ponadto wiele popularnych bibliotek open-source (libcurl, libxml2, SQLite, itp.) pochodzi z OS X i są dostępne do dynamicznego łączenia. Jeśli nie chcesz, nie musisz używać kakao ani niczego specyficznego dla jabłek.

Jeśli chcesz używać kakao w pewnych fragmenty aplikacji, spójrz na Objective-C++. Możesz mieszać C++ i Objective - C w tym samym pliku, nadając mu rozszerzenie. mm lub klikając prawym przyciskiem myszy plik w Xcode i wybierając Get Info > Ogólne, a następnie zmieniając typ pliku na sourcecode.cpp.objcpp. Druga opcja jest przydatna, jeśli masz .plik cpp, w którym chcesz użyć Objective-C w specyficznym dla Mac pliku # ifdef.

 4
Author: Matt Stevens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-08 18:24:57

Choć to pytanie sprzed lat...

Próbowałem zrobić wrapper c++ z niektórych klas Cocoa .

To było całkiem miłe doświadczenie. C++ zapewniało lepsze bezpieczeństwo typu niż Objective-C i sprawiało, że pisałem mniej kodu. Ale czas kompilacji i bezpieczeństwo pamięci są gorsze. Jest to możliwe, ale niektóre dynamiczne funkcje nie były łatwe w obsłudze. Myślę, że nie ma sensu zajmować się tym na C++.

W każdym razie mój projekt został ostatecznie porzucony z powodu Zapowiedzi Swift. Wyczyścił wszystkie powody, dla których chciałem na początku używać C++ i zapewnia jeszcze więcej i lepiej.

 2
Author: eonil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-02 17:59:11

Jeśli piszesz aplikację czysto graficzną, tzn. rysujesz wszystko za pomocą kodu, rozważ openFrameworks . Jest to opensource graficzny język programowania zbudowany na bazie C / C++. Posiada addony , które pozwalają na rozszerzenie języka. Mają dodatek do iphone. Wierzę, że pochodzi z biblioteki i projektów XCode, które pomogą Ci kompilować aplikacje dla iPhone i iPod touch.

 0
Author: milesmeow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-01 04:37:04