wake-up-neo.com

Verwenden Sie C ++ mit Cocoa anstelle von Objective-C?

Ich würde gerne Anwendungen schreiben, die C++ und die Cocoa-Frameworks verwenden, weil Apple macht Carbon 64-Bit nicht fähig. C++ scheint in seiner Implementierung unter Linux und Windows, aber unter Mac OS ziemlich Vanilla zu sein X Es scheint, als wären zusätzliche Apple spezifische Codeteile erforderlich (wie ein Obj-C-Wrapper). Es scheint auch, dass Apple) Entwickler zum Schreiben zwingt Objective-C statt C++, obwohl ich mich irren könnte.

Ich versuche, einen Weg zu finden, um Code auf dem Mac zu schreiben, der leicht plattformübergreifend zu halten wäre. Es wäre sehr ineffizient, Code in C++ für Linux/Windows zu schreiben und dann große Teile in Objective-C neu zu schreiben.

Gibt es eine Möglichkeit, Code in C++ zu schreiben, der zukünftig und in Xcode unterstützt wird? Wenn dies möglich ist, wie würde ich C++ und Objective-C in Xcode mischen? Vielen Dank.

121
Brock Woolf

Sie können eine Cocoa-Anwendung nicht vollständig in C++ schreiben. Cocoa stützt sich bei vielen seiner Kerntechnologien, wie Schlüsselwertbindungen, Delegaten (Cocoa-Stil) und dem Zielaktionsmuster, in hohem Maße auf die späten Bindungsfähigkeiten von Objective-C. Die späten Bindungsanforderungen machen es sehr schwierig, die Cocoa-API in einer kompilierzeitgebundenen, typisierten Sprache wie C++ zu implementieren. Sie können natürlich eine reine C++ - App schreiben, die unter OS X ausgeführt wird. Die Cocoa-APIs können einfach nicht verwendet werden.

Sie haben also zwei Möglichkeiten, um Code zwischen C++ - Apps auf anderen Plattformen und Ihrer Cocoa-basierten Anwendung zu teilen. Die erste besteht darin, die Modellschicht in C++ und die GUI in Cocoa zu schreiben. Dies ist ein gängiger Ansatz, der von einigen sehr großen Apps verwendet wird, einschließlich Mathematica . Ihr C++ - Code kann unverändert bleiben (Sie benötigen keine "funky" -Erweiterungen Apple), um C++ unter OS X zu schreiben oder zu kompilieren.) Ihre Controller-Ebene wird wahrscheinlich Objective-C++ verwenden (möglicherweise die "funky" Apple Erweiterung, auf die Sie sich beziehen). Objective-C++ ist eine Obermenge von C++, genau wie Objective-C eine Obermenge von C. In Objective-C++ können Sie objc-style erstellen Nachrichtenübermittlung (wie [some-objc-object callMethod];) innerhalb einer C++ - Funktion. Umgekehrt können Sie C++ - Funktionen aus dem ObjC-Code heraus aufrufen:

@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

Weitere Informationen zu Objective-C++ finden Sie in der Objective-C-Sprache Anleitung . Die Ansichtsebene kann dann reines Objective-C sein.

Die zweite Option ist die Verwendung eines plattformübergreifenden C++ - Toolkits. Das Qt Toolkit könnte in die Rechnung passen. Plattformübergreifende Toolkits werden von Mac-Benutzern im Allgemeinen verachtet, weil sie nicht alle Details des Erscheinungsbilds genau richtig wiedergeben und Mac-Benutzer eine verbesserte Benutzeroberfläche für Mac-Anwendungen erwarten. Qt macht einen überraschend guten Job, und abhängig von der Zielgruppe und der Verwendung Ihrer App kann es gut genug sein. Darüber hinaus verlieren Sie einige der OS X-spezifischen Technologien wie Core Animation und einige QuickTime-Funktionen, obwohl die Qt-API ungefähre Ersetzungen enthält. Wie Sie bereits erwähnt haben, wird Carbon nicht auf 64-Bit portiert. Da Qt auf Carbon-APIs implementiert ist, mussten Trolltech/Nokia Qt auf die Cocoa-API portieren, um die 64-Bit-Kompatibilität zu gewährleisten. Mein Verständnis ist, dass die nächste Version von Qt (derzeit in Release Candiate ) diesen Übergang abschließt und unter OS X 64-Bit-kompatibel ist. Wenn Sie möchten, sollten Sie einen Blick auf die Quelle von Qt 4.5 werfen sind an der Integration von C++ und der Cocoa-APIs interessiert.


ⁱ Für eine Weile stellte Apple die Cocoa-API für Java zur Verfügung, die Bridge erforderte jedoch umfangreiche manuelle Anpassungen und war nicht in der Lage, die weiter entwickelten Technologien wie die oben beschriebenen Schlüsselwert-Bindungen zu verarbeiten. Derzeit dynamisch typisierte, laufzeitgebundene Sprachen wie Python, Ruby usw. sind die einzige echte Option zum Schreiben einer Cocoa-App ohne Objective-C (obwohl diese Bridges natürlich Objective-C unter der Haube verwenden).

110
Barry Wark

Nun, es mag albern klingen, aber tatsächlich können wir reinen C++ - Code schreiben, um eine GUI für Mac OS X zu erstellen, aber wir müssen eine Verknüpfung zum Cocoa-Framework herstellen.

/*
 * 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;
}
65
FX. J. Adi Lima

Ja, Sie können einfach C++ verwenden (d. H. In * .cpp-Dateien schreiben) und sogar C++ und Objective-C in * .mm-Dateien mischen (Standard-Objective-C-Code wird in * .m-Dateien gespeichert).

Natürlich müssen Sie weiterhin Objective-C für Ihre Benutzeroberfläche verwenden und Objective-C-Wrapper für Ihre C++ - Objekte erstellen. Eine andere Möglichkeit ist, zu Qt zu wechseln. Dies ist ein C++ Framework, das Windows, Mac OS X und Linux unterstützt und mit der nächsten Version 4.5 unter der LGPL veröffentlicht wird.

17
fhe

Ja, Sie können sie mischen.

Sie müssen Objective-C verwenden, um Ihre GUI-Objekte direkt zu bearbeiten und Benachrichtigungen von ihnen zu erhalten.

Diese Objective-C-Objekte können C++ - Logik direkt aufrufen, wenn Sie sie in MM-Dateien anstelle der reinen Objective-C-M-Dateien ablegen. Beachten Sie, dass möglicherweise (viel) ältere Ratschläge angezeigt werden, die die Verwendung von .M in Großbuchstaben als Hinweis auf Objective-C++ empfehlen. Dies ist jedoch sehr unübersichtlich und kann Sie und den Compiler verwirren.

Sie müssen nicht jedes einzelne C++ - Objekt umbrechen, aber Ihr Objective-C-Code muss Zeiger darauf enthalten.

Apple veröffentlicht keine Beispiele mehr, die zeigen, wie das geht.

Es gibt ein großartiges Video von Peter Steinberger, das bei Realm gehostet wird [Objective] C++: Was könnte möglicherweise schief gehen? Ich kann es jedem empfehlen, der noch Objective-C++ verwendet, und Sie können das Transkript schnell überfliegen.

9
Andy Dent

Wenn Sie nur Vanilla C++ verwenden möchten, wird dies absolut unterstützt und unterscheidet sich wirklich nicht von jeder anderen Plattform. Xcode hat sogar eine Vorlage dafür unter Datei> Neues Projekt> Befehlszeilendienstprogramm> C++ - Tool. Einige der gängigen Open-Source-Bibliotheken (libcurl, libxml2, sqlite usw.) werden mit OS X ausgeliefert und stehen für dynamische Verknüpfungen zur Verfügung. Sie müssen keinen Kakao oder irgendetwas Apple-spezifisches verwenden, wenn Sie nicht möchten.

Wenn Sie Cocoa in bestimmten Bereichen Ihrer App verwenden möchten, werfen Sie einen Blick auf Objective-C++ . Sie können C++ und Objective-C in derselben Datei mischen, indem Sie der Datei die Erweiterung .mm zuweisen oder indem Sie mit der rechten Maustaste auf die Datei in Xcode klicken und Info abrufen> Allgemein auswählen und den Dateityp in sourcecode.cpp.objcpp ändern. Die zweite Option ist nützlich, wenn Sie eine CPP-Datei haben, in der Sie Objective-C in einem Mac-spezifischen #ifdef verwenden möchten.

4
Matt Stevens

Obwohl dies eine jahrelange Frage ist ...

Ich habe versucht, C++ - Wrapper für einige Cocoa-Klassen zu erstellen .

Es war eine schöne Erfahrung. C++ bot eine bessere Typensicherheit als Objective-C und brachte mich dazu, weniger Code zu schreiben. Die Kompilierungszeit und die Speichersicherheit sind jedoch schlechter. Es ist möglich, aber einige dynamische Funktionen waren nicht einfach zu handhaben. Ich denke, es macht keinen Sinn, sich mit C++ zu befassen.

Trotzdem wurde mein Projekt aufgrund der Ankündigung von Swift endgültig eingestellt. Es löschte alle Gründe, aus denen ich C++ zuerst verwenden wollte, und bietet noch mehr und besser.

1
Eonil

Wenn Sie eine rein grafische Anwendung schreiben, also alles mit Code zeichnen, ziehen Sie openFrameworks in Betracht. Es ist eine grafische Open Source-Programmiersprache, die auf C/C++ aufbaut. Es hat Addons , mit denen die Sprache erweitert werden kann. Sie haben ein Addon für das iPhone . Ich glaube, dass es mit der Bibliothek und den XCode-Projekten geliefert wird, mit denen Sie Apps für das iPhone und den iPod touch kompilieren können.

0
milesmeow