我在iOS应用上使用C ++库。其中一个函数为我提供了一个包含C枚举的std::vector
。我想在Objective C(而不是Object C ++)中使用这些数据,因此我需要将此数组转换为等效的Objective C数据结构。我正在使用一个将C ++转换为Objective C的桥接类。
我的代码看起来有点像:
typedef enum
{
Error0 = 0,
Error1 = 1,
Error2 = 2
} MyError;
class ListenerImpl : public Listener
{
public:
ListenerImpl(Listener* listener) : _listener(listener) {}
void onError(std::vector<MyError> errors) override
{
// Calling Objective C listener (listener class should not be using Objective C++)
[_listener onError:convertToObjC(errors)];
}
void handleError(MyError error, int someExtraData) {
// Error values are returned back to C++ so if any mapping is to be used it needs to be bi-directional.
}
private:
// The question is how to implement this function and what is a good return value here.
ArrayRetValue convertToObjC(std::vector<MyError> & errors)
{
// Not sure how to accomplish this
}
__weak Listener* _listener;
}
我的问题是:如何以可维护的方式实现这一点?
答案 0 :(得分:0)
在.h文件中:
#if __OBJC__
typedef NSArray *ArrayRetValue;
#else
typedef void *ArrayRetValue;
#endif
在.mm文件中(你需要它来混合C ++和Obj-C代码):
NSMutableArray * ListenerImpl::convertToObjC(std::vector<MyError> & errors)
{
NSMutableArray *objCErrors = [NSMutableArray arrayWithCapacity:errors.size()];
for (auto error: errors) {
[objCErrors addObject:[NSNumber numberWithInt:error]];
}
return objCErrors;
}
此外,您还需要将onError
函数移动到.mm文件,否则您将无法在C ++代码中使用此类。
答案 1 :(得分:0)
经过深思熟虑,我决定使用NSArray和仿制药的组合。通过这种方式,我可以明确地了解数据,因为我使用的是Objective-C对象,所以我不必担心C数组可能会发生内存泄漏。
为了实现这一点,我必须为我的C enum创建一个Objective-C等效对象(因为NSArray需要一个类型)。因此我创建了ErrorEnumObj
。
以下是完整的解决方案:
typedef enum
{
Error0 = 0,
Error1 = 1,
Error2 = 2
} MyError;
@interface ErrorEnumObj : NSObject
@property (nonatomic) int intValue;
+ (instancetype) objWithEnum:(MyError) myError;
- (MyError) getEnumValue;
@end
@implementation ErrorEnumObj
+ (instancetype) objWithEnum:(MyError) error
{
ErrorEnumObj * obj = [ErrorEnumObj new];
obj.intValue = (int)error;
return obj;
}
- (MyError) getEnumValue
{
return (MyError)self.intValue;
}
@end
class ListenerImpl : public Listener
{
public:
ListenerImpl(Listener* listener) : _listener(listener) {}
void onError(std::vector<MyError> errors) override
{
NSMutableArray<ErrorEnumObj *> * array = [NSMutableArray<ErrorEnumObj *> new];
for (auto&& myError : errors)
{
[array addObject:[ErrorEnumObj objWithEnum:myError]];
}
[_listener onError:array];
}
private:
__weak Listener* _listener;
}
如果要在多个枚举上使用这种解决方案,可以使用宏来创建EnumObj(声明和实现)(以创建类似解决方案的模板)。