Обёртка Objective-C C ++ Неполное определение ошибки типа - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь написать оболочки Objective-c для существующих классов C ++. У меня есть заголовок Objective-c в Click.h:

#import <Foundation/Fundation.h> 
@class CClick; // forward declaration of C++ class
@interface Click : NSObject
@end

Тогда у меня есть реализация оболочки в Click.mm:

#import "CClick.h"// import of C++ 
#import "Click.h" // objc import
@interface Click ()
@property (nonatomic, readonly) CClick *clickInternal;
@end
@implementation Click
... 
- (NSString *) uri
{
const char* uri = self.clickInternal->getUri(); // here I have error with incomplete definition of type 'CClick'

CClick - это мой класс C ++, у которого есть только некоторые свойства и метод получения для них.

Когда я пытаюсь построить свой проект, я получаю: неполное определение типа 'CClick'

Определение метода getUri в CClick.h на c ++:

#include <string> 
#include <vector>

using namespace std;

namespace MyTest {

class CClick {

public:
    string uri;
    string id;

    string getUri() {
        return uri;
    }

    string getId() {
        return id;
    }
};

}

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Чтобы написать класс Wrapper, вы должны создать класс .mm. Из вашего Вопроса неясно, вложена ли ваша реализация в класс .mm. Это говорит компилятору, что ваш класс хочет получить доступ (или содержит) код на C ++. (Google Objective-C ++)

Неопробованный псевдо-пример. Класс C ++ Foo и класс Wrapper Bar.

Заголовок объектива C:

#import <Foundation/Fundation.h>     
@interface Bar : NSObject
+ (NSString *) myString;
@end

Цель C ++ Реализация:

#include "Foo.h"
@implementation Bar
 + (NSString *) myString{
    return [NSString stringWithUTF8String: Foo::getMyString().c_str()];
}
@end

Ловушки:

  • Заголовок не должен содержать код / ​​ссылки C ++. В противном случае вы сможете импортировать его только в классы Objective-C ++.
  • Преобразование типов может быть болью. Всегда применяйте примитивные преобразования типов.

Как обращаться с объектными отношениями и жизненными циклами. Например. когда удалять ваш объект C ++, если он содержится в объекте Objective-C, - это отдельная тема, но вы должны подумать - вот почему я использовал статический вызов в своем примере.

0 голосов
/ 15 мая 2018

Похоже, вы забыли использовать CClick с namespace MyTest. Проверьте мой код ниже.

#import <Foundation/Fundation.h>
namespace MyTest {
class CClick; // forward declaration of C++ class
}
@interface Click : NSObject
@end

Файл реализации.

@interface Click ()
@property (nonatomic, readonly) MyTest::CClick *clickInternal;
@end

Или просто добавьте using namespace MyTest;

Важное замечание от @Richard Hodges:

using namespace std; очень плохая идея. Использование его в заголовочном файле - это катастрофа для себя и всех, кто включает ваш ядовитый заголовочный файл. Тебе нужно остановить это прямо сейчас.

...