Я придумал вполне управляемый ответ. Насколько чистым вы хотите, чтобы это было, полностью зависит от того, сколько работы вы готовы делать.
Во-первых, возьмите свой класс C ++ и создайте «функции-оболочки» C для взаимодействия с ним. Например, если у нас есть этот класс C ++:
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);
};
Затем мы реализуем эти функции C ++:
#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;
}
Заголовок моста затем содержит:
#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
В Swift мы теперь можем создать экземпляр объекта и взаимодействовать с ним следующим образом:
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!
Итак, как видите, решение (которое на самом деле довольно простое) состоит в том, чтобы создать оболочки, которые будут создавать экземпляр объекта и возвращать указатель на этот объект. Затем его можно передать обратно в функции-оболочки, которые могут легко обработать его как объект, соответствующий этому классу, и вызвать функции-члены.
Делаем его чище
Хотя это фантастическое начало и доказывает, что вполне возможно использовать существующие классы C ++ с тривиальным мостом, он может быть еще чище.
Очистка этого будет просто означать, что мы удалим UnsafeMutablePointer<Void>из середины нашего кода Swift и инкапсулируем его в класс Swift. По сути, мы используем те же функции-оболочки C / C ++, но взаимодействуем с ними с помощью класса Swift. Класс Swift поддерживает ссылку на объект и, по сути, просто передает все вызовы ссылок на методы и атрибуты через мост объекту C ++!
После этого весь код моста полностью инкапсулируется в класс Swift. Несмотря на то, что мы все еще используем мост C, мы эффективно используем объекты C ++ прозрачно, не прибегая к их перекодированию в Objective-C или Objective-C ++.