2011-04-12 3 views
1

Objective-C에서 OpenCV 정적 라이브러리를 사용하여 일부 이미지 처리를 수행하고 있으며 내 응용 프로그램이 잘 작동하고 있지만 장치 자체에서는 다소 느립니다. 처리의 큰 덩어리는 실제로 미리 수행 할 수 있으므로이 데이터를 직렬화하여 앱이 시작될 때이 데이터를로드하기로 결정했습니다.C++ 인스턴스 변수를 사용하여 Objective-C 객체를 아카이브/직렬화

serialize/archive해야하는 데이터는 CvSeq (openCV 시퀀스 - 값 시퀀스에 대한 포인터) 유형의 객체에 있습니다. 기본적으로이 파일을 저장하여 나중에로드 할 수 있습니다.

@implementation MyObject 

@synthesize point = _point; 
@synthesize description = _description; 

- (id)initWithCoder:(NSCoder *)decoder { 
    if (self = [super init]) { 
     self.point = [decoder decodeObjectForKey:@"point"]; 
     self.description = [decoder decodeObjectForKey:@"description"]; 
    } 
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)encoder { 
    [encoder encodeObject:self.point forKey:@"point"]; 
    [encoder encodeObject:self.description forKey:@"description"]; 
} 

@end 

그러나 decodeObjectForKey에 :와 encodeObject : 나는 거기에서 NSCoding 프로토콜과 인코딩/디코딩에 부착 된 클래스를 만드는하여이 작업을 수행 할 수 있다고 생각 통화가 나는 오류가

error: cannot convert 'objc_object*' to 'CvSeq*' in argument passing 

내 코드에 문제가 있습니까? 아니면 객관적이지 않은 C 인스턴스 변수가 내 객체에있는 것과 동일한 것을 얻을 수 있도록 다른 경로를 사용해야합니까?

+0

헤더 파일도 게시 할 수 있습니까? – Felix

답변

6

Objective-C의 직렬화 코드는 C++ 클래스를 보관하는 방법을 알지 못합니다. 이를 위해 코드를 명시 적으로 작성해야합니다. 위의 코드에서 "설명"이 CvSeq *라고 가정하면 CvSeq을 Cocoa가 보관하는 방법을 알고있는 것으로 변환하는 메소드를 작성해야합니다. 가장 효율적인 계획이 아니더라도 NSString을 시작하는 것이 가장 쉽습니다.

NSString* NSStringFromCvSeq(CvSeq* cppObj) 
{ 
    // You have to write this, but at it's simplest it might be something like... 
    return [NSString stringWithFormat: @"%d|%d|%d", cppObj->foo, cppObj->bar, cppObj->baz]; 
} 

CvSeq* NewCvSeqFromNSString(NSString* encodedString) 
{ 
    // You have to write this, but at it's simplest it might be something like... 
    NSScanner* scanner = [NSScanner scannerWithString: encodedString]; 
    [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString: @"|"]]; 
    int foo = [scanner scanInt]; 
    int bar = [scanner scanInt]; 
    int baz = [scanner scanInt]; 

    return new CvSeq(foo, bar, baz); 
} 

- (id)initWithCoder:(NSCoder *)decoder { 
    if (self = [super init]) { 
     self.point = [decoder decodeObjectForKey:@"point"]; 
     self.description = NewCvSeqFromNSString([decoder decodeObjectForKey:@"description"]); 
    } 
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)encoder { 
    [encoder encodeObject:self.point forKey:@"point"]; 
    [encoder encodeObject: NSStringFromCvSeq(self.description) forKey:@"description"]; 
} 

여기서 중요한 테이크 아웃 코코아는 임의의 유형 (이미 NSCoding을 채택 목표 - C 타입 제외) 보관하는 방법을 모르고이 없다는이며, 접착제의 일종없이 "무료"는 C++ 객체를 보관하지 않습니다 왜냐하면 C++ 객체는 NSCoding 프로토콜을 채택 할 방법이 없기 때문입니다.

희망 하시겠습니까?

1

dataWithBytes 메서드가있는 NSData 클래스는 자체 인코딩/직렬화 대신 Objective-C world의 OpenCV Mat 데이터를 아래와 같이 처리하는 데 도움이 될 수 있습니다.

NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()]; 

NSData 클래스로 전송 된 후 파일에 저장할 수 있습니다.

+0

모든 C++ 객체가 포인터 유형 멤버가없는 POD 클래스이거나 (여기에있는 것처럼) 객체의 기본 데이터를 명시 적으로 역 참조하는 경우이 작업은 가능하지만 코딩을위한 일반적인 솔루션은 아닙니다 Objective-C를 사용하는 C++ 객체. – ipmcc

+0

@ipmcc Objective-C를 사용하여 C++ 객체를 인코딩하는 일반적인 솔루션이 있습니까? 그렇다면 아직 찾지 못했습니다. 하나를 찾는 것을 좋아할 것입니다 !!! – livingtech

+2

@livingtech 숨을 멈추지 마십시오. – ipmcc

관련 문제