ฉันได้คำตอบที่จัดการได้อย่างสมบูรณ์แบบแล้ว ความสะอาดที่คุณต้องการให้เป็นขึ้นอยู่กับจำนวนงานที่คุณเต็มใจทำ
ขั้นแรกให้ใช้คลาส C ++ ของคุณและสร้างฟังก์ชัน C "wrapper" เพื่อเชื่อมต่อกับมัน ตัวอย่างเช่นถ้าเรามีคลาส 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!
ดังที่คุณเห็นวิธีแก้ปัญหา (ซึ่งจริงๆแล้วค่อนข้างง่าย) คือการสร้าง Wrapper ที่จะสร้างอินสแตนซ์ของวัตถุและส่งตัวชี้กลับไปยังวัตถุนั้น จากนั้นสามารถส่งกลับไปยังฟังก์ชัน wrapper ซึ่งสามารถถือว่าเป็นอ็อบเจ็กต์ที่สอดคล้องกับคลาสนั้นและเรียกใช้ฟังก์ชันสมาชิก
ทำให้สะอาดขึ้น
แม้ว่านี่จะเป็นการเริ่มต้นที่ยอดเยี่ยมและพิสูจน์ให้เห็นว่าเป็นไปได้อย่างสมบูรณ์ที่จะใช้คลาส C ++ ที่มีอยู่กับบริดจ์เล็กน้อย แต่ก็สามารถทำได้ดีกว่า
การทำความสะอาดสิ่งนี้หมายความว่าเราลบออกUnsafeMutablePointer<Void>
จากตรงกลางของรหัส Swift ของเราและห่อหุ้มไว้ในคลาส Swift โดยพื้นฐานแล้วเราใช้ฟังก์ชัน Wrapper C / C ++ เดียวกัน แต่เชื่อมต่อกับคลาส Swift คลาส Swift จะรักษาการอ้างอิงอ็อบเจ็กต์และโดยพื้นฐานแล้วเพียงแค่ส่งการเรียกใช้เมธอดและแอ็ตทริบิวต์ทั้งหมดผ่านบริดจ์ไปยังอ็อบเจ็กต์ C ++!
เมื่อทำสิ่งนี้แล้วรหัสบริดจ์ทั้งหมดจะถูกห่อหุ้มไว้ในคลาส Swift อย่างสมบูรณ์ แม้ว่าเราจะยังใช้สะพาน C อยู่ แต่เราก็ใช้วัตถุ C ++ ได้อย่างมีประสิทธิภาพอย่างโปร่งใสโดยไม่ต้องใช้การเข้ารหัสใหม่ใน Objective-C หรือ Objective-C ++