Je viens de changer mes fichiers .m en .mm et d'utiliser C ++. Existe-t-il un moyen de faire de même avec Swift?
la source
Je viens de changer mes fichiers .m en .mm et d'utiliser C ++. Existe-t-il un moyen de faire de même avec Swift?
Non. Lorsque vous passez de .m à .mm, vous passez en fait d'Objective-C à un autre langage (qui présente de nombreuses différences subtiles) appelé Objective-C ++. Vous n'utilisez donc pas vraiment C ++; vous utilisez Objective-C ++ qui accepte la plupart des C ++ en entrée (de la même manière que C ++ accepte la plupart mais pas tous les C en entrée). Quand je dis que ce n'est pas tout à fait C ++, considérez un fichier C ++ qui comprend une variable nommée nil
(qui est C ++ légal), puis essayez de compiler cela en Objective-C ++.
Swift n'a pas la même relation. Ce n'est pas un sur-ensemble de C ou C ++, et vous ne pouvez pas utiliser directement l'un ou l'autre dans un .swift
fichier.
"Utiliser Swift avec Cocoa et Objective-C" nous dit également:
Vous ne pouvez pas importer du code C ++ directement dans Swift. Au lieu de cela, créez un wrapper Objective-C ou C pour le code C ++.
.mm
vos fichiers et être (presque) terminé. Ce n'est pas le cas avec Swift.nil
, commeint nil
La confusion peut provenir de l'hypothèse que simplement changer une extension de fichier de
.m
à.mm
est tout ce dont vous avez besoin pour relier les langues, alors qu'en réalité, cela ne fait rien de ce genre. Ce n'est pas le.mm
frottement avec.cpp
, c'est le.h
collecteur qui ne doit absolument pas être unC++
collecteur.Même projet: Oui.
Dans le même projet, vous pouvez facilement mélanger C , C ++ , Objective-C , Objective C ++ , Swift et même Assembly .
...Bridging-Header.h
: vous exposez C , Objective-C et Objective-C ++ à Swift en utilisant ce pont<ProductModuleName>-Swift.h
: expose automatiquement vos classes Swift marquées d'un@objc
à Objective-C.h
: c'est la partie la plus délicate, car ils sont utilisés de manière ambiguë pour toutes les saveurs de C , ++ ou pas, Objective ou pas. Quand a.h
ne contient pas un seul mot-clé C ++ , commeclass
, il peut être ajouté au...Bridging-Header.h
, et exposera la fonction correspondante.c
ou les.cpp
fonctionnalités qu'il déclare. Sinon, cet en-tête doit être encapsulé dans une API pure C ou Objective-C .Même fichier: Non.
Dans le même fichier, vous ne pouvez pas mélanger tous les 5. Dans le même fichier source :
.swift
: vous ne pouvez pas mélanger Swift avec quoi que ce soit.m
: Vous pouvez mélanger Objective-C avec C . ( @Vinzzz ).mm
: vous pouvez mélanger Objective-C avec C ++ . Ce pont est Objective-C ++ . ( @Vinzzz )..c
: C pur.cpp
: vous pouvez mélanger C ++ et Assembly ( @Vality ).h
: C , C ++ , Objective-C ou Objective-C ++ omniprésent et ambigu , donc la réponse est que cela dépend.Références
la source
J'ai écrit un projet Xcode 6 simple 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 un Objective C et une fonction C ++ à partir du Swift.
La clé est de créer un en-tête partagé Project-Bridging-Header.h et d'y placer les en-têtes Objective C.
Veuillez télécharger le projet comme exemple complet.
la source
ObjCtoCPlusPlus.h
/ `` .mm` existe dans le seul but de fournir une interface Ob-C au code C ++ - c'est le pont, qui est ici un composant nécessaire. Laissez les includes où ils se trouvent et ajoutez une méthode dans lesObjCtoCPlusPlus.…
fichiers pour chaque méthode C ++ à laquelle vous devez accéder. Vous feriez bien de lire sur sourcemaking.com/design_patterns/adapterVous pouvez également ignorer le fichier Objective-C entre les deux. Ajoutez simplement un fichier d'en-tête C avec un fichier source .cpp. Avoir uniquement des déclarations C dans le fichier d'en-tête et inclure tout code C ++ dans le fichier source. Incluez ensuite le fichier d'en-tête C dans le ** - Bridging-Header.h.
L'exemple suivant renvoie un pointeur vers un objet C ++ (struct Foo) afin que Swift puisse stocker dans un COpaquePointer au lieu d'avoir struct Foo défini dans l'espace global.
Fichier Foo.h (vu par Swift - inclus dans le fichier de pontage)
À l'intérieur du fichier source Foo.cpp (non vu par Swift):
la source
extern "C"
envelopper l'en-tête à l'endroit où il est inclus plutôt#ifdef
qu'éd dans le fichier d'en-tête lui-même. Brillant!Je viens de faire un petit exemple de projet utilisant Swift, Objective-C et C ++. C'est une démonstration de l'utilisation de l'assemblage OpenCV sous iOS. L'API OpenCV est C ++, nous ne pouvons donc pas lui parler directement depuis Swift. J'utilise une petite classe wrapper dont le fichier d'implémentation est Objective-C ++. Le fichier d'en- tête est propre Objective-C, donc Swift peut lui parler directement. Vous devez faire attention à ne pas importer indirectement de fichiers C ++ dans les en-têtes avec lesquels Swift interagit.
Le projet est ici: https://github.com/foundry/OpenCVSwiftStitch
la source
Voici ma tentative d'un outil clang pour automatiser la communication C ++ / rapide. Vous pouvez instancier des classes C ++ à partir de swift, hériter de la classe C ++ et même remplacer 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
la source
Swift n'est pas directement compatible avec C ++. Vous pouvez contourner le problème en encapsulant votre code C ++ avec Objective-C et en utilisant l'encapsuleur Objective C dans Swift.
la source
J'ai aussi un programme de démonstration pour opencv de combinaison rapide.
Vous pouvez le télécharger sur https://github.com/russj/swift_opencv3_demo .
Plus d'informations sur la démo http://flopalm.com/opencv-with-swift/ .
la source
Non, pas dans un seul fichier.
Cependant, vous pouvez utiliser C ++ dans Swift Projects sans avoir besoin d'une bibliothèque statique ou d'un framework. Comme d'autres l'ont dit, la clé est de créer un en-tête de pontage Objective-C qui #inclut des en-têtes C ++ compatibles C qui sont marqués comme C compatibles avec l' astuce extern "C" {} .
Tutoriel vidéo: https://www.youtube.com/watch?v=0x6JbiphNS4
la source
D'autres réponses sont légèrement inexactes. Vous pouvez en fait mélanger Swift et [Objective-] C [++] dans le même fichier, mais pas tout à fait comme vous le souhaiteriez.
Ce fichier (c.swift) se compile en un exécutable valide avec à la fois
swiftc c.swift
etclang -x objective-c c.swift
la source
Un truc (parmi tant d'autres) est que
Vous avez besoin d'un en- tête séparé pour votre fichier obj-c ++ de pontage ...
Vous ne pouvez pas simplement lancer @interface et @implementation dans le même fichier .mm comme on le fait souvent normalement.
Donc, dans votre fichier d'en-tête de pontage, vous avez
Linkage.hpp a l '@interface pour Linkage et Linkage.mm a la @implementation pour .mm
Puis
... vous n'incluez pas en fait "yourCpp.hpp" dans Linkage.hpp.
Vous ne mettez que
#include "yourCpp.hpp"
dans le fichier Linkage.mm, pas dans le fichier Linkage.hpp.Dans de nombreux exemples / tutoriels en ligne, le rédacteur place simplement @interface et @implementation dans le même fichier .mm, comme on le fait souvent.
Cela fonctionnera dans des exemples de pontage cpp très simples, mais,
Le problème est:
si votre yourCpp.hpp a des fonctionnalités C ++, ce qu'il sera sûrement (comme la première ligne
#include <something>
), alors le processus échouera.Mais si vous n'avez tout simplement pas le
#include "yourCpp.hpp"
dans le fichier d'en- tête Linkage (c'est bien de l'avoir dans le fichier .mm, vous en aurez évidemment besoin) - cela fonctionne.Encore une fois, ce n'est malheureusement qu'un conseil dans l'ensemble du processus.
la source
Au cas où cela serait utile à quiconque, j'ai également un bref tutoriel sur l'appel d'une simple bibliothèque statique C ++ à partir d'un utilitaire de ligne de commande Swift trivial. Il s'agit d'une preuve de concept très simple.
Aucun Objective-C impliqué, juste Swift et C ++. Le code d'une bibliothèque C ++ est appelé par un wrapper C ++ qui implémente une fonction avec une liaison externe "C". Cette fonction est ensuite référencée dans l'en-tête de pontage et appelée depuis Swift.
Voir http://www.swiftprogrammer.info/swift_call_cpp.html
la source
Je propose un lien vers SE-0038 dans la ressource officielle, décrit comme Ceci maintient les propositions de changements et d'améliorations visibles par l'utilisateur du langage de programmation Swift.
Le statut actuel est qu'il s'agit de la demande de fonctionnalité qui a été acceptée mais pas encore planifiée.
Ce lien est destiné à orienter tous ceux qui recherchent cette fonctionnalité dans la bonne direction
la source