완벽하게 관리 할 수있는 답변을 찾았습니다. 이것이 얼마나 깨끗하길 바라는지는 전적으로 당신이 기꺼이 할 일의 양에 달려 있습니다.
먼저 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 브리지를 사용하고 있지만 Objective-C 또는 Objective-C ++로 다시 코딩하지 않고도 C ++ 객체를 투명하게 효과적으로 사용하고 있습니다.