136 votes

Puis-je mélanger Swift et C++ ? Comme les fichiers .mm d'Objective-C

Je viens de changer mes fichiers .m en .mm et j'utilise C++. Y a-t-il un moyen de faire la même chose avec Swift ?

112voto

Rob Napier Points 92148

Non. Lorsque vous passez de .m à .mm, vous passez en fait d'Objective-C à un langage différent (qui présente de nombreuses différences subtiles) appelé Objective-C++. Vous n'utilisez donc pas vraiment le C++, mais l'Objective-C++ qui accepte la plupart des C++ en entrée (de la même manière que le C++ accepte la plupart mais pas tout le C en entrée). Quand je dis que ce n'est pas tout à fait du C++, considérez un fichier C++ qui inclut une variable nommée nil (qui est du C++ légal) et ensuite essayer de le compiler en Objective-C++.

Swift n'a pas la même relation. Il ne s'agit pas d'un sur-ensemble de C ou de C++, et vous ne pouvez pas utiliser directement l'un ou l'autre dans une application de type .swift fichier.

"Utiliser Swift avec Cocoa et Objective-C" nous dit aussi :

Vous ne pouvez pas importer du code C++ directement dans Swift. Il faut plutôt créer un wrapper Objective-C ou C pour le code C++.

6 votes

Je suggère qu'Objective-c++ n'est pas un langage différent mais un mélange de c++ et d'Objective-c. La différence est subtile mais elle est toujours présente.

1 votes

Comment "nil" est-il légal en C++ ? Cela n'existe pas (du moins en C++ standard) Veuillez fournir un autre exemple.

1 votes

Mais d'après votre réponse, il semble que vous puissiez effectivement appeler du c++ depuis swift, à condition qu'il existe une interface C pour ces méthodes. Si l'OP pense comme moi, il espère partager du code logique entre plusieurs plateformes.

72voto

Gian Luigi Romita Points 161

J'ai écrit un simple projet Xcode 6 qui montre comment mélanger du code C++, Objective C et Swift :

https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

En particulier, l'exemple appelle une fonction Objective C et une fonction C++ du Swift.

La clé est de créer un en-tête partagé Project-Bridging-Header.h et d'y mettre les en-têtes Objective C.

Veuillez télécharger le projet en tant qu'exemple complet.

0 votes

Merci pour ce Gian !

0 votes

Merci pour cet exemple, mais si je veux déplacer le #import "CPlusPlus.h" de ObjCtoCPlusPlus.mm vers le fichier ObjCtoCPlusPlus.h, le compilateur renvoie cette erreur : <inconnu>:0 : error : failed to import bridging header '/Users/Ale/Downloads/shared-master/C-ObjC-Swift/Performance_Console/Performance_Console/Performance_Console-Bridging-Header.h' il est possible de déplacer cette importation dans le fichier header ?

0 votes

@API : Non, vous ne comprenez pas. ObjCtoCPlusPlus.h /``.mm` existe dans le seul but de fournir une interface Ob-C au code C++ - c'est le pont, qui est un composant nécessaire ici. Laissez les includes où ils sont, et ajoutez une méthode dans le fichier ObjCtoCPlusPlus.… pour chaque méthode C++ à laquelle vous devez accéder. Vous feriez bien de lire sourcemaking.com/design_patterns/adapter

27voto

foundry Points 15423

Je viens de réaliser un petit projet d'exemple en utilisant Swift, Objective-C et C++. Il s'agit d'une démo de l'utilisation du stitching d'OpenCV dans iOS. L'API OpenCV est en C++ donc on ne peut pas lui parler directement depuis Swift. J'utilise une petite classe wrapper dont le fichier d'implémentation est en Objective-C++. Le site En-tête est propre à l'Objective-C, et Swift peut donc s'y référer directement. Il faut veiller à ne pas importer indirectement des fichiers de type C++ dans les en-têtes avec lesquels Swift interagit.

Le projet est ici : https://github.com/foundry/OpenCVSwiftStitch

0 votes

Je pense que cela répond à un problème que j'ai rencontré aujourd'hui en essayant d'utiliser une bibliothèque tierce KudanCV avec Swift. Mon en-tête de pontage importe leur fichier .h qui contient des importations de <memory> <strings> et <vectors> qui, je suppose, proviennent de bibliothèques ou de fichiers C++, en conséquence, mon code Swift ne compile pas. Je serais reconnaissant si quelqu'un pouvait me dire s'il existe un moyen de contourner ce problème... ou si je dois réécrire tout mon code en Objective-C.

1 votes

@RocketGarden - Le fichier d'en-tête de KudanCV est C++. Vous pourriez écrire un wrapper qui fonctionne de la même manière que ma classe wrapper d'exemple. OU vous réécrivez les parties de votre application qui ont besoin de parler à KudanCV en Objective-C++ (avec un en-tête Objective-C). Vous n'auriez pas besoin de réécrire les parties de votre projet qui ne sont pas concernées par KudanCV.

0 votes

Merci pour cela, je l'ai réalisé environ 5 minutes plus tard, mais c'est utile de l'avoir en mémoire pour les autres.

13voto

Sandy Points 51

Voici ma tentative d'un outil clang pour automatiser la communication C++/swift. Vous pouvez instancier des classes C++ depuis swift, hériter de classes C++ et même surcharger des méthodes virtuelles dans swift.
Il analysera la classe C++ que vous souhaitez exporter vers swift et générera automatiquement le pont Objective-C/Objective-C++.

https://github.com/sandym/swiftpp

8voto

Austin Points 3222

Swift n'est pas directement compatible avec C++. Vous pouvez contourner ce problème en enveloppant votre code C++ en Objective-C, et en utilisant l'enveloppe Objective C dans Swift.

0 votes

Voilà ce que j'ai fait. J'ai écrit un article sur la façon d'intégrer le c++ dans un projet swift : learningswift.brightdigit.com/integration-c-plus-plus-swift

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X