Ich habe eine perfekt handhabbare Antwort ausgearbeitet. Wie sauber dies sein soll, hängt ganz davon ab, wie viel Arbeit Sie bereit sind.
Nehmen Sie zuerst Ihre C ++ - Klasse und erstellen Sie C-Wrapper-Funktionen, um eine Schnittstelle zu ihr herzustellen. Wenn wir zum Beispiel diese C ++ - Klasse haben:
class MBR {
std::string filename;
public:
MBR (std::string filename);
const char *hexdump();
const char *imageType();
const char *bootCode();
const char *partitions();
private:
bool readFile(unsigned char *buffer, const unsigned int length);
};
Wir implementieren dann diese C ++ - Funktionen:
#include "MBR.hpp"
using namespace std;
const void * initialize(char *filename)
{
MBR *mbr = new MBR(filename);
return (void *)mbr;
}
const char *hexdump(const void *object)
{
MBR *mbr;
static char retval[2048];
mbr = (MBR *)object;
strcpy(retval, mbr -> hexdump());
return retval;
}
const char *imageType(const void *object)
{
MBR *mbr;
static char retval[256];
mbr = (MBR *)object;
strcpy(retval, mbr -> imageType());
return retval;
}
Der Bridge-Header enthält dann:
#ifndef ImageReader_hpp
#define ImageReader_hpp
#ifdef __cplusplus
extern "C" {
#endif
const void *initialize(char *filename);
const char *hexdump(const void *object);
const char *imageType(const void *object);
#ifdef __cplusplus
}
#endif
#endif
Von Swift aus können wir jetzt das Objekt instanziieren und wie folgt damit interagieren:
let cppObject = UnsafeMutablePointer<Void>(initialize(filename))
let type = String.fromCString(imageType(cppObject))
let dump = String.fromCString(hexdump(cppObject))
self.imageTypeLabel.stringValue = type!
self.dumpDisplay.stringValue = dump!
Wie Sie sehen können, besteht die Lösung (die eigentlich ziemlich einfach ist) darin, Wrapper zu erstellen, die ein Objekt instanziieren und einen Zeiger auf dieses Objekt zurückgeben. Dies kann dann an die Wrapper-Funktionen zurückgegeben werden, die es leicht als ein Objekt behandeln können, das dieser Klasse entspricht, und die Elementfunktionen aufrufen können.
Sauberer machen
Dies ist zwar ein fantastischer Start und beweist, dass es durchaus machbar ist, vorhandene C ++ - Klassen mit einer trivialen Brücke zu verwenden, aber es kann noch sauberer sein.
Dies zu bereinigen würde einfach bedeuten, dass wir den UnsafeMutablePointer<Void>
Code aus der Mitte unseres Swift-Codes entfernen und ihn in eine Swift-Klasse einkapseln. Im Wesentlichen verwenden wir dieselben C / C ++ - Wrapperfunktionen, verbinden sie jedoch mit einer Swift-Klasse. Die Swift-Klasse verwaltet die Objektreferenz und übergibt im Wesentlichen alle Methoden- und Attributreferenzaufrufe über die Bridge an das C ++ - Objekt!
Danach ist der gesamte Bridging-Code vollständig in der Swift-Klasse gekapselt. Obwohl wir immer noch eine C-Brücke verwenden, verwenden wir C ++ - Objekte effektiv transparent, ohne sie in Objective-C oder Objective-C ++ neu codieren zu müssen.