EXC_BAD_ACCESS Xcode 来自我的 objective-c++ 和 swift 桥接头文件中的 c++ 包装器
EXC_BAD_ACCESS Xcode from my c++ wrapper in objective-c++ and swift bridging header
我正在使用 openCV 和用 C++ 创建的实用程序 class "Detector" 开发应用程序。我想为 c++ class 创建一个 objective-c++ 包装器 "DetectorWrapper" 并在 Swift (桥接头)中使用这个包装器。但是知道当我尝试从 DetectorWrapper 调用函数时,我的应用程序崩溃并出现错误:EXC_BAD_ACCESS
我在某处读到允许在 Swift 中使用 objective-c++ class,我不能在 DetectorWrapper.h 中包含 c++ 文件,所以我使用类型 id.
这是我的 C++ class:"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
指的是同一个文件,这只是一个错字。
我正在使用 openCV 和用 C++ 创建的实用程序 class "Detector" 开发应用程序。我想为 c++ class 创建一个 objective-c++ 包装器 "DetectorWrapper" 并在 Swift (桥接头)中使用这个包装器。但是知道当我尝试从 DetectorWrapper 调用函数时,我的应用程序崩溃并出现错误:EXC_BAD_ACCESS
我在某处读到允许在 Swift 中使用 objective-c++ class,我不能在 DetectorWrapper.h 中包含 c++ 文件,所以我使用类型 id.
这是我的 C++ class:"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
指的是同一个文件,这只是一个错字。