Saya telah menyusun jawaban yang bisa dikelola dengan sempurna. Seberapa bersih Anda menginginkan hal ini sepenuhnya didasarkan pada seberapa banyak pekerjaan yang ingin Anda lakukan.
Pertama, ambil kelas C ++ Anda dan buat fungsi "pembungkus" C untuk berinteraksi dengannya. Misalnya, jika kita memiliki kelas C ++ ini:
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);
};
Kami kemudian mengimplementasikan fungsi C ++ ini:
#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;
}
Header jembatan kemudian berisi:
#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
Dari Swift, kita sekarang dapat membuat instance objek dan berinteraksi dengannya seperti:
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!
Jadi, seperti yang Anda lihat, solusinya (yang sebenarnya cukup sederhana) adalah membuat pembungkus yang akan membuat instance objek dan mengembalikan pointer ke objek itu. Ini kemudian dapat dikirimkan kembali ke fungsi pembungkus yang dapat dengan mudah memperlakukannya sebagai objek yang sesuai dengan kelas itu dan memanggil fungsi anggota.
Menjadikannya Lebih Bersih
Meskipun ini adalah awal yang fantastis dan membuktikan bahwa sangat layak untuk menggunakan kelas C ++ yang ada dengan jembatan yang sepele, ini bahkan bisa lebih bersih.
Membersihkan ini berarti kita menghapus UnsafeMutablePointer<Void>bagian tengah kode Swift kita dan merangkumnya ke dalam kelas Swift. Pada dasarnya, kami menggunakan fungsi pembungkus C / C ++ yang sama tetapi menghubungkannya dengan kelas Swift. Kelas Swift mempertahankan referensi objek dan pada dasarnya hanya meneruskan semua panggilan referensi metode dan atribut melalui jembatan ke objek C ++!
Setelah melakukan ini, semua kode penghubung benar-benar dikemas dalam kelas Swift. Meskipun kami masih menggunakan C bridge, kami secara efektif menggunakan objek C ++ secara transparan tanpa harus menggunakan pengodean ulang di Objective-C atau Objective-C ++.