L'interaction avec des classes C++ de Swift
J'ai une importante bibliothèque de classes écrites en C++. Je suis en train de faire usage d'entre eux à travers un certain type de pont au sein de Swift plutôt que de les réécrire comme code Swift. La motivation principale est que le code C++ représente une bibliothèque de base qui est utilisé sur de multiples plateformes. Effectivement, je suis juste de créer rapidement une base de l'INTERFACE utilisateur pour permettre la fonctionnalité de base pour fonctionner sous OS X.
Il y a d'autres questions à se demander "Comment puis-je appeler une fonction C++ de Swift." C'est pas ma question. À pont à une fonction C++, le suivant fonctionne très bien:
Définir un en-tête de transition par le biais de "C"
#ifndef ImageReader_hpp
#define ImageReader_hpp
#ifdef __cplusplus
extern "C" {
#endif
const char *hexdump(char *filename);
const char *imageType(char *filename);
#ifdef __cplusplus
}
#endif
#endif /* ImageReader_hpp */
Code Swift peut maintenant appeler directement les fonctions de
let type = String.fromCString(imageType(filename))
let dump = String.fromCString(hexdump(filename))
Ma question est plus spécifique. Comment puis-je instancier et de manipuler un Classe C++ de l'intérieur Swift? Je n'arrive pas à trouver tout ce qui est publié sur ce.
- J'ai personnellement eu recours à l'écriture de la plaine de l'Objectif-wrapper C++ fichiers qui exposent un Objectif-C classe qui reproduit tous les appels C++ et simplement les transmet à une instance de la classe C++. Dans mon cas, le nombre de classes C++ et des appels est petit, donc il n'est pas particulièrement intensif en main d'œuvre. Mais je vais retenir sur la promotion de ce titre de réponse, dans l'espoir que quelqu'un aura trouver quelque chose de mieux.
- Eh bien, c'est quelque chose... nous allons attendre et voir (et l'espoir).
- J'ai reçu une suggestion via IRC pour écrire un Swift classe wrapper qui maintient un vide pointeur vers le véritable objet C++ et expose les méthodes requises, qui sont, en effet, vient de passer à travers par l'intermédiaire de la C pont et le pointeur vers l'objet.
- Une mise à jour de cette, Swift 3.0 est maintenant, et malgré les promesses, C++ interopérabilité est maintenant marqué comme "Hors de portée."
Vous devez vous connecter pour publier un commentaire.
J'ai travaillé sur un parfaitement gérable réponse. Comment nettoyer vous souhaitez que cet être est entièrement basé sur la quantité de travail que vous êtes prêt à le faire.
Tout d'abord, prenez votre classe C++ et de créer C "wrapper" les fonctions d'interface avec elle. Par exemple, si nous avons cette classe C++:
Nous avons ensuite mettre en œuvre ces fonctions C++:
Le pont d'en-tête contient alors:
De Swift, nous pouvons maintenant instancier l'objet et d'interagir avec elle de la sorte:
Donc, comme vous pouvez le voir, la solution (qui est en fait plutôt simple) est de créer des emballages qui va instancier un objet et retourne un pointeur sur cet objet. Cela peut ensuite être transmis dans les fonctions wrapper qui peut facilement traiter comme un objet conforme à la classe et appeler les fonctions de membre.
En Le Rendant Plus Clair
Alors que c'est un excellent début et prouve qu'il est tout à fait réalisable à utiliser les classes C++ avec une mince pont, il peut être encore plus propre.
Nettoyage cela signifie simplement que l'on retire le
UnsafeMutablePointer<Void>
à partir du milieu de notre code Swift et de l'encapsuler dans un rapide de classe. Essentiellement, nous utilisons le même C/C++ des fonctions wrapper, mais une interface avec une Swift de la classe. La Swift classe maintient la référence de l'objet et essentiellement juste passe tous des méthodes et des attributs de référence des appels à travers le pont de l'objet C++!Ayant fait cela, tous les de la transition code est complètement encapsulé dans des rapides de classe. Même si nous sommes encore à l'aide d'un C pont, nous sommes en mesure d'utiliser des objets en C++ de manière transparente, sans avoir à recourir à recoder en Objective-C ou Objective-C++.
Swift n'a pas de C++ interop actuellement. C'est un objectif à long terme, mais il est très peu probable de se produire dans un avenir proche.
En plus de votre propre solution, il y a une autre façon de le faire. Vous pouvez l'appeler ou lui écrire directement du code C++ en objective-c++.
Donc, si vous créez un objectif-wrapper C++ sur le dessus de votre code C++ et de créer une interface adaptée
et appel objective-C++ le code de votre code swift. Pour être en mesure d'écrire objective-C++ code que vous avez peut-être renommer l'extension de fichier de .m pour .mm
Ne pas oublier de libérer la mémoire allouée par vos objets en C++ lorsque approprié.
Comme une autre réponse mentionné, à l'aide de ObjC++ pour interagir est beaucoup plus facile. Juste le nom de vos fichiers .mm au lieu de .m et xcode/clang, vous donne accès à c++ dans ce fichier.
Noter que ObjC++ ne prend pas en charge C++ héritage. Je veux que vous sous-classe d'une classe c++ en ObjC++, vous ne pouvez pas. Vous aurez à écrire le sous-classe en C++ et l'enrouler autour d'un ObjC++ classe.
Puis utilisez la transition de l'en-tête que vous utilisez normalement pour appeler objc de swift.
Vous pouvez utiliser Scapix Langue Pont automatiquement pont C++ pour Swift (entre autres langues). Pont de code automatiquement généré à la volée directement à partir de C++ fichiers d'en-tête. Voici un exemple:
C++:
Swift: