web-dev-qa-db-fra.com

Utiliser C ++ avec Cocoa au lieu d'Objective-C?

Je voudrais écrire des applications qui utilisent C++ et les frameworks Cocoa car Apple ne permet pas à Carbon de prendre en charge 64 bits. C++ semble être assez vanille dans son implémentation sous Linux et Windows mais sous Mac OS X il semble que des éléments de code supplémentaires Apple soient requis (comme un wrapper Obj-C). Il semble également que Apple oblige les développeurs à écrire) Objective-C plutôt que C++, bien que je puisse me tromper.

J'essaie de trouver un chemin pour écrire du code sur le Mac qui serait facile à garder multiplate-forme. Avoir à écrire du code en C++ pour Linux/Windows puis à réécrire de grandes parties dans Objective-C serait très inefficace.

Existe-t-il un moyen d'écrire du code en C++ qui sera supporté à l'avenir et supporté par Xcode? De plus, si cela est possible, comment pourrais-je mélanger C++ et Objective-C dans Xcode? Merci.

121
Brock Woolf

Vous ne pouvez pas écrire une application Cocoa entièrement en C++. Cocoa s'appuie fortement sur les capacités de liaison tardives d'Objective-C pour bon nombre de ses technologies de base telles que les liaisons de valeur-clé, les délégués (style Cocoa) et le modèle action-cible. Les exigences de liaison tardives rendent très très difficile l’implémentation de l’API de Cocoa dans un langage typé, lié à la compilation, comme C++. Vous pouvez bien sûr écrire une application C++ pure qui s'exécute sous OS X. Elle ne peut tout simplement pas utiliser les API Cocoa.

Vous avez donc deux options si vous souhaitez partager du code entre des applications C++ sur d'autres plates-formes et votre application Cocoa. La première consiste à écrire la couche modèle en C++ et l'interface graphique dans Cocoa. Il s'agit d'une approche commune utilisée par de très grandes applications, notamment Mathematica . Votre code C++ peut rester inchangé (vous n'avez pas besoin de "funky" Apple pour écrire ou compiler C++ sur OS X). Votre couche de contrôleur utilisera probablement Objective-C++ (peut-être le "funky" Apple à laquelle vous vous référez). Objective-C++ est un sur-ensemble de C++, tout comme Objective-C est un sur-ensemble de C. En Objective-C++, vous pouvez créer le style objc. message transmettant des appels (comme [some-objc-object callMethod];) depuis une fonction C++. Inversement, vous pouvez appeler des fonctions C++ à partir de code ObjC, comme suit:

@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

Vous pouvez en savoir plus sur Objective-C++ dans le langage Objective-C guide . La couche de vue peut alors être pure Objective-C.

La deuxième option consiste à utiliser un toolkit C++ multiplate-forme. Le toolkit Qt pourrait convenir. Les kits Mac multiplate-forme sont généralement méprisés par les utilisateurs de Mac car ils n’ont pas tous les détails et les détails sont exacts et les utilisateurs de Mac s’attendent à une finition parfaite de l’interface utilisateur des applications Mac. Qt fait un travail étonnamment bon, cependant, et en fonction du public cible et de l'utilisation de votre application, cela peut suffire. En outre, vous perdrez certaines technologies spécifiques à OS X, telles que Core Animation et certaines fonctionnalités de QuickTime, bien qu'il existe des remplacements approximatifs dans l'API Qt. Comme vous le signalez, Carbon ne sera pas porté en 64 bits. Depuis que Qt est implémenté sur les API Carbon, Trolltech/Nokia doit porter Qt sur l’API Cocoa pour le rendre compatible 64 bits. Si j'ai bien compris, la prochaine version de Qt (actuellement dans release candiate ) complète cette transition et est compatible 64 bits sur OS X. Vous pouvez consulter la source de Qt 4.5 si vous êtes intéressé par l’intégration de C++ et des API Cocoa.


ⁱ Pendant un certain temps Apple a rendu l'API Cocoa disponible pour Java, mais le pont nécessitait un réglage manuel approfondi et était incapable de gérer les technologies plus avancées telles que les liaisons de valeur par clé décrites ci-dessus. Actuellement, de manière dynamique. Les langages typés, liés à l'exécution, tels que Python, Ruby, etc., sont la seule véritable option pour écrire une application Cocoa sans Objective-C (bien que ces ponts utilisent bien entendu Objective-C sous le capot).

110
Barry Wark

Cela peut sembler idiot, mais en réalité, nous pouvons écrire du code C++ pur pour créer une interface graphique pour Mac OS X, mais nous devons établir une liaison avec le framework 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;
}
65
FX. J. Adi Lima

Oui, vous pouvez simplement utiliser C++ (c'est-à-dire l'écrire dans des fichiers * .cpp) et même mélanger C++ et Objective-C dans des fichiers * .mm (le code standard Objective-C est stocké dans des fichiers * .m).

Bien entendu, vous devez toujours utiliser Objective-C pour votre interface utilisateur et créer des wrappers Objective-C pour vos objets C++. Une autre option consiste à basculer vers Qt , un framework C++ prenant en charge Windows, Mac OS X et Linux - et qui sera publié sous LGPL avec la prochaine version 4.5.

17
fhe

Oui, vous pouvez les mélanger.

Vous devez utiliser Objective-C pour agir directement sur vos objets d'interface graphique et recevoir leurs notifications.

Ces objets Objective-C peuvent appeler directement la logique C++ si vous les mettez dans des fichiers .mm, au lieu des fichiers Objective-C .m purs. Notez que vous pouvez voir (beaucoup) de vieux conseils suggérant d'utiliser un .M majuscule pour indiquer Objective-C++, mais ceci est très floconneux et risque de vous semer la confusion, ainsi que celle du compilateur.

Vous n'avez pas besoin d'encapsuler chaque objet C++, mais votre code Objective-C devra contenir des pointeurs sur ceux-ci.

Apple ne publie plus d'échantillons montrant comment faire cela.

Il y a une superbe vidéo de Peter Steinberger hébergée chez Realm [Objectif] C++: Qu'est-ce qui pourrait éventuellement aller mal? Je le recommande vivement à quiconque utilise encore Objective-C++ et vous pouvez parcourir rapidement la transcription.

9
Andy Dent

Si vous cherchez simplement à utiliser plain Vanilla C++, cela est absolument pris en charge et ne diffère vraiment pas de celui de toute autre plate-forme. Xcode a même un modèle pour cela sous Fichier> Nouveau projet> Utilitaire de ligne de commande> Outil C++. En outre, un certain nombre de bibliothèques open source populaires (libcurl, libxml2, sqlite, etc.) sont fournies avec OS X et sont disponibles pour la liaison dynamique. Si vous ne le souhaitez pas, vous n’êtes pas obligé d’utiliser Cocoa ou quoi que ce soit d’Apple.

Si vous souhaitez utiliser Cocoa dans certaines parties de votre application, consultez Objective-C++ . Vous pouvez mélanger C++ et Objective-C dans le même fichier en lui attribuant une extension .mm ou en cliquant avec le bouton droit de la souris sur le fichier dans Xcode et en sélectionnant Lire les informations> Général, puis en changeant le type de fichier en sourcecode.cpp.objcpp. La deuxième option est utile si vous avez un fichier .cpp dans lequel vous souhaitez utiliser Objective-C dans un fichier #ifdef spécifique à Mac.

4
Matt Stevens

Bien que ce soit une question de plusieurs années ...

J'ai essayé de faire du wrapper C++ de certaines classes Cocoa .

C'était une belle expérience. C++ a fourni une meilleure sécurité de type que Objective-C et m'a obligé à écrire moins de code. Mais la compilation du temps et la sécurité de la mémoire sont pires. C'est possible, mais certaines fonctionnalités dynamiques n'étaient pas faciles à gérer. Je pense que cela n’a aucun sens de traiter cela en C++.

Quoi qu'il en soit, mon projet a finalement été abandonné en raison de l'annonce de Swift. Il a effacé toutes les raisons pour lesquelles je voulais utiliser le C++ au début, et fournit encore plus et mieux.

1
Eonil

Si vous écrivez une application purement graphique, c’est-à-dire que vous dessinez tout en utilisant du code, considérez openFrameworks . C'est un langage de programmation graphique open source construit sur C/C++. Il a addons qui permettent aux gens d’étendre la langue. Ils ont n addon pour l'iphone . Je pense que cela vient avec la bibliothèque et les projets XCode qui vous aideront à compiler des applications pour iPhone et iPod touch.

0
milesmeow