c++ - EXC_BAD_ACCESS Xcode 来自我在 Objective-C++ 中的 C++ 包装器和 Swift 桥接头
问题描述
我正在开发一个使用 openCV 和用 C++ 创建的实用程序类“检测器”的应用程序。我想为 c++ 类创建一个objective-c++ 包装器“DetectorWrapper”,并在 Swift(桥接头)中使用这个包装器。但是知道当我尝试从 DetectorWrapper 调用函数时,我的应用程序崩溃并出现错误:EXC_BAD_ACCESS
我在哪里读到允许在 Swift 中使用 Objective-C++ 类,我不能在 DetectorWrapper.h 中包含 C++ 文件,所以我使用类型 ID。
这是我的 C++ 类:“Detector.h”
#include "opencv2/opencv.hpp"
class Detector
{
public:
// Constructor
Detector(int inputPlayerIdx);
// Scan the input video frame
void scanFrame(cv::Mat frame);
// Tracking API
bool isTracking();
};
我的包装:“DetectorWrapper.h”
@interface DetectorWrapper : NSObject
@end
@interface DetectorWrapper ()
@property (nonatomic, readwrite, assign) id bld;
- (id)init: (int) inputPlayerIdx;
- (void)dealloc;
- (void) scanFrame: (UIImage*) frame;
- (bool) isTracking;
@end
“DetectorWrapper.mm”
#import "DetectorWrapper.h"
#import "Detector.hpp"
#import "UIImage+OpenCV.h"
@implementation DetectorWrapper
@synthesize bld = _bld;
- (id)init: (int) inputPlayerIdx {
self = [super init];
if (self) {
_bld = (__bridge id) new Detector(inputPlayerIdx);
}
return self;
}
- (void)dealloc {
//[self->_bld dealloc];
//[super dealloc];
//delete _bld;
}
- (void) scanFrame: (UIImage*) frame{
[self->_bld scanFrame:frame];
}
- (bool) isTracking{
return [self->_bld isTracking];
}
@end
在 Swift 中使用它:
let detector = DetectorWrapper(2)
detector.isTracking()
使用桥接头中的文件“Detector.h”。
调用 .isTracking 时出现“EXC_BAD_ACCESS”错误我根本不明白这个问题以及如何解决这个问题。也许我只是在编写我的 Objective-C++ 包装器时犯了一个错误,我不习惯这种语言。有任何想法吗?
解决方案
这里的一个问题是,一个 C++ 对象被当作一个 Objective-C 对象来使用,而这些类型的对象是不可互换的。
为了说明和简单起见,让我们消除该scanFrame
方法。然后DetectorWrapper.h
变成
@interface DetectorWrapper : NSObject
- (id)init: (int) inputPlayerIdx;
- (void)dealloc;
- (bool) isTracking;
@end
和包装器实现:
@implementation DetectorWrapper
{
// Instance variable to hold a C++ object pointer
Detector * ptrDetector;
}
- (id)init: (int) inputPlayerIdx {
self = [super init];
if (self) {
ptrDetector = new Detector(inputPlayerIdx);
}
return self;
}
- (void)dealloc {
// Don't want to leak the C++ Detector instance
delete ptrDetector;
}
- (bool) isTracking{
return ptrDetector->isTracking();
}
@end
请注意,当您重新引入 时scanFrame
,您将不能只传递UIImage*
给ptrDetector->scanFrame()
,这需要cv::Mat
,您必须在包装器中做一些魔术scanFrame
才能在两种类型之间进行转换,但这本身就是一个主题,我认为。顺便说一句,我假设在您的示例中Detector.h
并Detector.hpp
引用同一个文件,这只是一个错字。