我有一个C ++库,需要将其集成到Swift中。我以为那是可行的,直到我意识到我的Objective-C包装器中的C ++对象已被释放。
MyCPPClass.hpp
class MyCPPClass {
std:string myString;
int myInt;
}
MyCPPProcessor.hpp
class MyCPPProcessor {
public:
static MyCPPClass getMeACPPClass();
}
MyCPPProcessor.cpp
MyCPPClass MyCPPProcessor::getMeACPPClass() {
CPPClass myCPP;
myCPP.myString = "This is my String";
myInt = 23;
return myCPP;
}
CPPClassWrapper.h
@interface CPPClassWrapper : NSObject
@end
CPPClassWrapper.mm
@interface CPPClassWrapper()
@property MyCPPClass *myCPPClass;
@end
@implementation CPPClassWrapper
-(instancetype) initWithMyCPPClass:(MyCPPClass *)myCPPClass
{
self.myCPPClass = myCPPClass;
return self;
}
@end
MyProcessorWrapper.h
@interface MyProcessorWrapper : NSObject
+(MyClassWrapper *) getMeACPPClass;
@end
MyProcessWrapper.mm
@implementation MyProcessWrapper
+(MyCPPCLassWrapper *) getMeACPPClass
{
MyCPPClass myCPPClass = MyCPPProcessor::getMeACPPClass()
CPPClassWrapper *cppClassWrapper = [[CPPClassWrapper alloc] initWithMyCPPCLass: & myCPPClass];
(1) return cppClassWrapper;
}
@end
到第(1)行时,一切都按预期进行。 cppClassWrapper有一个指向myCPPClass的指针,可以对其进行检查和验证。
但是,当它传递到Swift层时,cppClassWrapper.myCPPClass被释放并调用其析构函数。
class MyCPPProcessorBridge: MyCPPProcessorWrapper
{
public static func getMeACPPClass -> MyCPPClassBridge
{
let myCPPWrapper:MyCPPClassWrapper = super.getMeACPPClass()
(2) return MyCPPClassBridge(wrapper: myCPPWrapper)
}
}
当我们到达第(2)行时,myCPPWrapper失去了指向myCPPClass的指针,因为它已被释放。
如何防止此版本发布?
答案 0 :(得分:3)
这与将对象传递给Swift没有任何关系。
问题出在您的+getMeACPPClass
方法中。变量myCPPClass
具有自动存储功能。它位于堆栈上。当该方法返回时,其堆栈空间无效,并且该对象被销毁。您的Objective-C CPPClassWrapper
类仅包含指向同一存储的指针。 C ++对象销毁后,该指针将悬空。
因此,您的点(1)是该变量有效时的 last 点。控件一返回到该方法的调用者,它将立即失效。
您需要执行以下任一操作:1)在std::shared_ptr
和+getMeACPPClass
中在堆上分配对象并使用CPPClassWrapper
进行管理;或2)让CPPClassWrapper
容纳一个对象,而不仅仅是一个指针,并且它将拥有最初在+getMeACPPClass
中创建的对象的副本。