Создание оболочки Objective-C для библиотеки C ++ - PullRequest
8 голосов
/ 17 ноября 2010

Я пытаюсь создать оболочку в Objective-C, поэтому мне не нужно писать c ++ вне классов библиотеки.

Основной файл библиотеки - LLAHProcessor.h .cpp

My Wrapperis LLAHProcessorWrapper.h .mm

Он компилируется нормально, но когда я добавляю LLAHProcessorWrapper в другой класс, (скажем, UIView) в качестве переменной-члена, я получаю сотни ошибок, например:

#include <map> : Map no such a file or directory

и в каждом классе / структуре c ++:

Expected specifier-qualifier list before ClassName

Как будто компилятор не распознает код c ++.

Интересно, чего мне здесь не хватает.Должно ли это быть что-то с тем фактом, что я добавил это в Свойства цели Xcode:?

Other Link Flags : -lstdc++ -lz

Или, может быть, мне нужно добавить новые флаги здесь?

Заранее спасибо

Ответы [ 3 ]

6 голосов
/ 17 ноября 2010

Ваша проблема в том, что .m файлы скомпилированы как C вместо C ++. Таким образом, когда компилятор сталкивается с любым C ++ даже в заголовочном файле во время компиляции файла .m, он будет раздражен.

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

// LLAHProcessorWrapper.h

#if defined __cplusplus
class MyCPPClass;    // forward class declaration
#else
typedef struct MyCPPClass MyCPPClass;   // forward struct declaration
#endif

@interface MyOCClass : NSObject
{
@private
    MyCPPClass* cppObject;
} 

// methods and properties

@end

Поскольку вы никогда не разыменовываете элементы cppObject вне файла .mm, не имеет значения, что вы никогда не предоставите полное определение для структуры.

Вы бы new и delete указали в -init и -dealloc соответственно. Вы должны включить полное объявление класса C ++ в LLAHProcessorWrapper.mm.

4 голосов
/ 17 ноября 2010

Все, что вам нужно сделать, это создать .mm, как вы это сделали, и компилятор должен позаботиться обо всем.

Предостережение в том, что в файлах .h нет ничего связанного с C ++, поскольку они могут / будут импортироваться другими файлами только Objective-C, и тогда все выходит из строя. Основная проблема заключается в том, что вы не можете определять типы C ++ непосредственно как переменные экземпляра для вашего класса-оболочки Objective-C, если только каждый отдельный файл .m не переименован в файл Objective-C ++ .mm.

Решение состоит в том, чтобы определить переменные экземпляра как void* в заголовочном файле и получить к ним доступ с помощью приведения типов из файла реализации. Самым простым решением для этого было бы получить доступ к переменной экземпляра с помощью частного свойства, которое будет для вас приведено.

В примере кода предполагается, что Foo - это класс C ++, определенный в Foo.h:

// FooWrapper.h
#import <Foundation/Foundation.h>

@interface FooWrapper : NSObject {
@private
  void* foo;
}
// Actual wrapper API for Foo…
@end


// FooWrapper.mm
#import "FooWrapper.h"
#include <map>
#include "Foo.h"

@interface FooWrapper ()
@property(nonatomic, assign) Foo* foo;
@end

@implementation FooWrapper
-(Foo*)foo {
  return (Foo*)foo;
}
-(void)setFoo:(Foo*)aFoo {
  foo = (void*)aFoo;
}
// Implementation of actual API for Foo…
@end
0 голосов
/ 17 ноября 2010

В любом файле заголовка (.h), в котором вы хотите сослаться на LLAHProcessorWrapper, используйте определения прямого класса вместо импорта, например так:

@class LLAHProcessorWrapper;
@interface SomeView : UIView {
  LLAHProcessorWrapper *wrapper;
}

и убедитесь, что соответствующий файл реализации имеет #include LLAHProcessorWrapper.h или #import LLAHProcessorWrapper.h.

Любой файл реализации, в котором вы #include или #import ваш заголовок должны иметь .mm в качестве суффикса, если LLAHProcessorWrapper.h или что-либо еще во всем дереве включения вообще имеет какой-либо синтаксис C ++ , Таким образом, наличие одного .mm файла имеет тенденцию означать, что огромные части кодовой базы должны переименовывать свои файлы в .mm.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...