我有一个C++库,我需要把它集成到SWIFT中。我认为它一直在工作,直到我意识到我的Objy-C包装器中的C++对象被释放了。
C++层
MyCPPClass.hpp公司

class MyCPPClass {
    std:string myString;
    int myInt;
}

mycpp处理器.hpp
class MyCPPProcessor {
    public:
        static MyCPPClass getMeACPPClass();
}

mycpp处理器.cpp
MyCPPClass MyCPPProcessor::getMeACPPClass() {
   CPPClass myCPP;
   myCPP.myString = "This is my String";
   myInt = 23;
   return myCPP;
}

目标C层
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的指针,因为它已被释放。
如何阻止此释放?

最佳答案

这和把你的东西交给斯威夫特没有关系。
问题出在你的+getMeACPPClass方法上。变量myCPPClass具有自动存储。它住在烟囱上。当该方法返回时,其堆栈空间将无效,并且该对象将被销毁。Objective-CCPPClassWrapper类只保存指向同一存储的指针。在C++对象被销毁后,该指针会悬空。
所以,你的点(1)是变量有效的最后一个点。一旦控件返回到该方法的调用方,它就无效。
您需要:1)在堆上分配对象并使用std::shared_ptr来管理它,在+getMeACPPClassCPPClassWrapper中都是这样;或者2)让CPPClassWrapper持有一个对象,而不仅仅是一个指针,它将拥有最初在+getMeACPPClass中创建的对象的副本。

10-08 08:13