У меня есть заголовочный файл C ++ (названный header.h
), который я хочу включить в мой проект Swift.
Поскольку фреймворк C ++, который я хочу включить, еще не закончен, у меня пока есть только заголовочный файл
Мой заголовочный файл C ++ header.h
выглядит примерно так:
#include <vector>
struct someStruct{
float someAttr;
}
class someClass{
public:
enum SomeEnum{
Option1,
Option2
}
void someFunc(const double value) {}
}
Проблема в том, когда я пытаюсь включить header.h
файл в project-Bridging-Header.h
он никогда не найдет вектор, который я включаю в header.h
Я пытался переименовать header.h
в header.hpp
,
Я попытался установить тип заголовка моста C ++ Header на правой панели.
Но никто из них не помог.
Я надеюсь, что некоторые из вас могут помочь мне понять, что я делаю неправильно.
К сожалению, невозможно напрямую использовать класс C ++ в Swift, см. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216-CH2-ID0:
Вы не можете импортировать код C ++ непосредственно в Swift. Вместо этого создайте
Обёртка Objective-C или C для кода C ++.
На самом деле, удобный способ упаковки C ++ для использования в Swift — Objective-C ++. Исходные файлы Objective-C ++ могут содержать смешанный код Objective-C и C ++. Вот быстрый частичный пример, основанный на фрагменте кода в вашем вопросе. Только someClass
здесь частично завернут. В производственном коде вам также необходимо учитывать управление памятью.
Заголовочный файл оболочки, mywrapper.h
, не имеет следов C ++:
#ifndef mywrapper_h
#define mywrapper_h
#import <Foundation/Foundation.h>
// This is a wrapper Objective-C++ class around the C++ class
@interface someClass_oc : NSObject
-(void)someFunc:(double)value;
@end
#endif /* mywrapper_h */
Вот реализация Objective-C ++, mywrapper.mm
, Пожалуйста, обратите внимание .mm
расширение. Вы можете создать файл Objective-C с .m
и затем переименуйте его.
#import "mywrapper.h"#import "header.h" // CAN import a C++ header here, in Objective-C++ code
// Use an extension on someClass_oc because we need to use someClass,
// but we couldn't do it in mywrapper.h,
// which is visible from Swift and thus can't contain C++ stuff.
@interface someClass_oc ()
{
someClass * ptrSomeClass;
}
@end
@implementation someClass_oc
-(id)init
{
// In this example ptrSomeClass is leaked...
ptrSomeClass = new someClass();
return self;
}
-(void)someFunc:(double)value
{
ptrSomeClass->someFunc(value);
}
@end
Теперь вы можете импортировать mywrapper.h
в заголовке моста, а затем сделать что-то вроде этого в Swift:
let x = someClass_oc()
x.someFunc(123.456)
Таким образом, вы можете создать объект в Swift, который поддерживается экземпляром вашего класса C ++.
Это просто быстрый пример, чтобы дать вам идею. Если вы столкнетесь с другими проблемами, они, вероятно, заслуживают отдельных вопросов.
Других решений пока нет …